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

时间:2014-01-04 07:41:59

标签: 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!
}

编译器抱怨两行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>(); }
};

然后一切都很好。请注意,基于标记为OK的main()行,当字符串为模板参数时,此问题特定于模板运算符TT AND(在2010年,但不在2012年),涉及临时。

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

1 个答案:

答案 0 :(得分: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)

我不知道为什么std::string的行为与其他类不同,很可能是构造函数和赋值运算符的丰富。

当为编译器提供多个选项来执行强制转换时,在这种情况下为double castFoo - &gt; string - &gt; const string&)失败。它也可以选择Foo - &gt; int - &gt; const string&或类似的东西。