Oli*_*ver 7 c++ string templates operator-keyword
以下编译在VS 2005中,但未在2010年或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!
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨两行main()不能转换.但是,如果我用operator TT()一组等效的重载替换模板定义,
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>(); }
};
Run Code Online (Sandbox Code Playgroud)
一切都很好.请注意,基于main()标记为OK 的行,当字符串为模板参数时,此问题特定于模板运算符TT AND(在2010年,但不在2012年),涉及临时.
这不是有效的代码吗?为什么在某些情况下有效?
字符串的复制构造函数之间似乎存在歧义。
使用这一行可以解决歧义:
std::string testStringLocal = (const std::string&)foo;
同样的情况也发生在operator=:
std::string testStringLocal; // define empty string
testStringLocal = (const std::string&)foo; //OK
testStringLocal = foo; // Fail in all VS compilers (VS2010, 2012, 2013)
Run Code Online (Sandbox Code Playgroud)
我不知道为什么std::string其行为与其他类不同,很可能是构造函数和赋值运算符的丰富性。
当为编译器提供多个选项来执行强制转换时,在这种情况下double cast( Foo-> string-> const string&) 它将失败。它还可以选择Foo-> int->const string&或类似的东西。