C++ 模板转换运算符字符串()不';不编译
以下内容在VS 2005中编制,但不是在2010或2012年: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
#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)