1

我想将自定义类转换为在 VS2005 中编译得很好的字符串。但是在 VS2012 中我得到了编译器错误error C2440: 'type cast' : cannot convert from 'A' to 'std::string'。我必须改变什么?这是我的例子:

    #include <string>

    using namespace std;

    class A
    {
    public:
      A& operator=(const char* c);
      operator string ();
      operator const char* ();

    private:
      string value;
    };

    A::operator string () { return string((const char*)(*this)); }
    A& A::operator = (const char* aValue)   { value = aValue; return *this; }
    A::operator const char *() { const char* wort = "Hello"; return wort; }

    int main() 
    {
      A a;
      string s = (string)a; // C2440
    }
4

3 回答 3

3

A问题是从to有两种可能的显式转换string- 通过转换运算符 to string; 或通过转换运算符 to const char *,然后通过转换构造函数 to string

简单地使转换隐式将解决歧义;第二个转换需要两个用户定义的转换,因此不能选择隐式转换:

string s = a;

但是,该类仍然有点不稳定,因为有时您可能需要显式转换。我会考虑删除至少一个隐式转换运算符——也许用显式运算符替换它们(如果你的编译器支持这样的东西),或者用命名函数替换它们(就像string它本身一样c_str())。

于 2013-03-01T15:03:54.390 回答
1

转换是模棱两可的。

远离 C 风格的强制转换,而更喜欢使转换显式。

#include <string>

using namespace std;

class A
{
public:
  A& operator=(const char* c);
  explicit operator string ();
  explicit operator const char* ();

private:
  string value;
};

A::operator string () { return string(static_cast<const char*>(*this)); }
A& A::operator = (const char* aValue)   { value = aValue; return *this; }
A::operator const char *() { const char* wort = "Hello"; return wort; }

int main() 
{
  A a;
  string s = static_cast<std::string>(a);
}
于 2013-03-01T15:03:14.190 回答
0

您的两个转换操作员互相踩踏。它们中的每一个都适用于隐式转换。但是显式强制转换就像直接调用构造函数。在您的代码中

string s = (string)a;

相当于

string s = static_cast<string>(a);

转换为类似的东西

string tmp(a);
string s(std::move(tmp)); // this move can be elided
// lifetime of tmp ends here

关键是直接初始化string tmp(a)。有两个可行的字符串构造函数:string(const string&)并且explicit string(const char *)您的两个转换允许调用任何一个。由于这两种转换顺序都不是更好,因此调用是模棱两可的。

顺便说一句,使用复制初始化而没有显式转换的版本并不模棱两可:

string s = a;

应该管用。取决于很脆,所以不推荐。

您应该制作转换运算符explicit(如果您使用的是 C++11)或删除其中一个。

于 2013-03-01T15:12:57.463 回答