有谁知道为什么 main 中的最后一行无法编译(注意是编译失败):
template <typename TT> inline TT getAs();
template <> string getAs() { return "bye"; }
template <> int getAs() { return 123; }
class Foo
{
public:
template <typename TT>
inline operator TT() const { return ::getAs<TT>(); }
template <typename TT>
inline string getAs() const { return ::getAs<TT>(); }
};
Foo tempFoo() { return Foo(); }
int main()
{
Foo foo;
string testStringLocal = foo; // OK
int testIntTemp = tempFoo(); // OK
string testStringTemp = tempFoo().getAs<string>(); // OK
const string& testStringTemp2 = tempFoo(); // OK
string testStringTemp3 = tempFoo(); //.getAs<string>(); // FAIL!
}
正如我对主要行的评论所指出的,
- 从 Foo 到字符串的隐式转换在非临时对象(例如 foo)上编译得很好,
- 以及转换为 int (或 long 等)时的临时对象
- 通过方法转换为字符串时它确实工作正常
- 以及如果类型
const string&
不是字符串
在VS2010上试过这个。请注意,上面的代码在 2005 年编译得很好,但我相信 2010 年是正确的。
如果我删除模板定义和特化并简单地明确定义每个重载,则通过运算符隐式转换为字符串可以正常工作:
class Foo
{
public:
operator string() const { return ::getAs<string>(); }
operator int() const { return ::getAs<int>(); }
...
};
我不想使用这种解决方法,因为它的可维护性较差。
有谁知道让 main() 的最后一行成功编译的另一种方法?我不认为对显式转换和模板化转换运算符的公认答案适用于此,因为无论是否涉及模板,都可能进行多种转换(char *、alloc、string),而且对象是临时对象的事实似乎很重要.
编辑:这篇文章中的原始代码显示了一些类内模板专业化,这是从我的原始源中为 SO 创建独立代码片段的人工制品(我将一些命名空间级专业化移动到类中,VS2010 没有抱怨)。问题不在于专业化。我修改了发布的代码以更接近原始代码(就像我刚刚所做的那样),不使用课堂专业化(当然问题仍然存在)。Derek 的回答表明它可能特定于 VS2010。