C++ 模板转换运算符字符串()不';不编译

C++ 模板转换运算符字符串()不';不编译,c++,string,templates,operator-keyword,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: tem

以下内容在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!
}
然后一切都会好起来。注意:根据标记为OK的
main()
行,当字符串为template param且(2010年,但不是2012年)涉及临时变量时,此问题特定于模板运算符TT


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

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

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

std::string testStringLocal=(const std::string&)foo

运算符=
也会发生同样的情况:

std::string testStringLocal;               // define empty string
testStringLocal = (const std::string&)foo; //OK
testStringLocal = foo;                     // Fail in all VS compilers (VS2010, 2012, 2013)
我不知道为什么
std::string
的行为与其他类不同,最有可能的原因是构造函数和赋值运算符的丰富


当编译器有多个选项来执行强制转换时,在这种情况下,
双强制转换(
Foo
->
string
->
->
)将失败。它也可以选择
Foo
->
int
->
const-string&
或类似的东西。

关于gcc和clang,以及VS2013。编译它不需要定义操作符std::string,只需定义模板版本,然后明确地调用它:
std::string testStringLocal=Foo.operator std::string()
@praetorian很高兴知道这可能只是编译器错误then@emilcondrea有趣的是,我不可能要求我的用户使用这种晦涩难懂的语法。谈论如何挫败操作员过载的全部目的@Scholli当然你不会,我只是指出编译器的错误可能在哪里。所以你不认为这是VC++编译器的错误吗?为了将
foo
转换为
常量字符串&
,编译器必须首先使用
运算符string()
,与转换为
字符串时必须使用的运算符string()相同,因此在一种情况下它能够找到正确的字符串构造函数,但在另一种情况下却找不到,这一事实使我认为它是一个编译器错误。我对你的答案非常满意,因为这是一个有用的解决方法,但它需要用户使用常量引用的强制转换,很少有人会想到尝试。我必须记录
getAs()
可以用于任何TT,而操作符TT()可以用于某些情况(待定)。可能是编译器错误,我不知道。需要阅读说明书才能完全给出答案。对我来说,这完全是理论上的。我永远不会写这样的代码,因为大多数开发团队的工程师经验很少,而且模板的使用有点太多(我的观点)。就我个人而言,我希望快速了解在每个语句中应该运行哪些代码。
std::string testStringLocal;               // define empty string
testStringLocal = (const std::string&)foo; //OK
testStringLocal = foo;                     // Fail in all VS compilers (VS2010, 2012, 2013)