gpt4 book ai didi

c++ - templated operator string() 在临时对象时不会编译

转载 作者:太空狗 更新时间:2023-10-29 21:22:17 24 4
gpt4 key购买 nike

有谁知道为什么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& 而不是 string

在 VS2010 上试过这个。请注意,上面的代码在 2005 年可以正常编译,但我相信 2010 年是正确的。

如果我删除模板定义和特化并简单地显式定义每个重载,则通过运算符隐式转换为字符串工作正常:

class Foo
{
public:
operator string() const { return ::getAs<string>(); }
operator int() const { return ::getAs<int>(); }
...
};

我不希望使用此解决方法,因为它不易维护。

有谁知道另一种方法可以让 main() 的最后一行成功编译?我不认为 Explicit conversion and templated conversion operator 的公认答案适用于此,因为无论是否涉及模板,都可能进行多种转换(char *、alloc、string),而且对象是临时对象这一事实似乎很重要。

编辑:这篇文章中的原始代码显示了一些类内模板特化,这是从我的原始源代码中为 SO 创建独立代码片段的产物(我将一些命名空间级别的特化移到了类和 VS2010 中没有提示)。问题是不是特化。我修改了发布的代码以更接近原始代码(就像我刚刚所做的那样),不使用类特化(当然问题仍然存在)。 Derek 的回答表明它可能特定于 VS2010。

最佳答案

不了解 Visual C++ 2010(我认为是 9.0 版),但您不能在类本身中特化模板化成员函数。根据我将此代码提供给的更多现代编译器发出的错误,它必须在命名空间范围内完成。

所以,

#include <string>
using namespace std;

class Foo
{
public:
template <typename TT> inline operator TT() const;
template <typename TT> inline TT getAs() const;
};

template <> inline Foo::operator string() const { return "hi"; }
template <> inline Foo::operator int() const { return 123; }
template <> inline string Foo::getAs() const { return "bye"; }

Foo tempFoo() { return Foo(); }

int main()
{
Foo foo;
string testStringLocal = foo; // OK
int testIntTemp = tempFoo(); // OK
string testStringTemp = tempFoo().getAs<string>(); // OK

string testStringTemp2 = tempFoo(); // OK!
}

使用 Visual C++ 12.0 和 g++ 4.7.2 编译良好。

关于c++ - templated operator string() 在临时对象时不会编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20897766/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com