模板化转换运算符string()无法编译

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年),涉及临时.

这不是有效的代码吗?为什么在某些情况下有效?

egu*_*gur 1

字符串的复制构造函数之间似乎存在歧义。

使用这一行可以解决歧义:

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&或类似的东西。