【发布时间】:2014-01-21 23:48:00
【问题描述】:
以下在 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() 行,当字符串是模板参数并且(在 2010 年,但不是在 2012 年)涉及临时时,此问题特定于模板运算符 TT。
这不是有效的代码吗?为什么它在某些情况下有效?
【问题讨论】:
-
Compiles 关于 gcc 和 clang,以及 VS2013。
-
你不需要定义 operator std::string 来编译它,你定义模板版本然后直接调用它:
std::string testStringLocal = foo.operator std::string(); -
@praetorian 很高兴知道可能只是编译器错误
-
@emilcondrea 很有趣,但我绝不会要求我的用户使用这种晦涩难懂的语法。谈论破坏运算符重载的全部目的!
-
@Schollii 当然你不会,我只是指出编译器错误可能在哪里。
标签: c++ string templates operator-keyword