The following compiles in VS 2005 but not in 2010 or 2012:
#include <string>
template <typename TT> TT getAs();
template <> std::string getAs() { return "bye"; }
template <> int getAs() { return 123; }
class Foo
{
public:
template <typename TT>
TT getAs() const { return ::getAs<TT>(); }
template <typename TT>
operator TT() const { return ::getAs<TT>(); }
};
Foo tempFoo() { return Foo(); }
int main()
{
Foo foo;
std::string testStringLocal = foo; // OK in 2010, FAIL in 2012
int testIntTemp = tempFoo(); // OK
std::string testStringTemp = tempFoo().getAs<std::string>(); // OK
const std::string& testStringTemp2 = tempFoo(); // OK
std::string testStringTemp3 = tempFoo(); // FAIL!
}
Compiler complains on two lines of main()
that conversion not possible. But if I replace the template definition of operator TT()
by a set of equivalent overloads,
class Foo
{
public:
template <typename TT>
TT getAs() const { return ::getAs<TT>(); }
operator std::string() const { return ::getAs<std::string>(); }
operator int() const { return ::getAs<int>(); }
};
then everything builds fine. Note based on the main()
lines that are marked OK that this problem is specific to template operator TT when string is template param AND (in 2010, but not in 2012) a temporary is involved.
Is this not valid code? Why is it valid in some cases?
There seems to be an ambiguity between string's copy constructors.
Using this line solves the ambiguity:
std::string testStringLocal = (const std::string&)foo;
The same happens with operator=
:
std::string testStringLocal; // define empty string
testStringLocal = (const std::string&)foo; //OK
testStringLocal = foo; // Fail in all VS compilers (VS2010, 2012, 2013)
I don't know why std::string
behaves differently than other classes, most likely the wealth of constructors and assignment operators.
When a compiler is given multiple options to perform a cast, and in this case a double cast
(Foo
-> string
-> const string&
) it will fail. It could also choose Foo
-> int
-> const string&
or something of the sort.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With