2013-03-01 71 views
1

我想将自定义类转换为在VS2005中编译的字符串。但在VS2012中,我收到编译器错误error C2440: 'type cast' : cannot convert from 'A' to 'std::string'。我需要改变什么?这是我的例子:如何将自定义类型转换为VS2012中的字符串?

#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 
    } 
+0

这工作好wth'VS2010'。 你可以看看这个答案,可能你会得到一些线索。 http://stackoverflow.com/questions/3558589/error-c2440-type-cast-cannot-convert-from-std-vector-iterator-ty-alloc – 2013-03-01 15:03:21

回答

3

的问题是,有两个可能的显式转换从Astring - 通过所述转换操作者string;或者通过转换运算符到const char *,然后通过转换构造函数到string

简单地使转换隐含将解决模糊性;第二次转换需要两个用户自定义的转换,因此不能被抽中的隐式转换:

string s = a; 

然而,类仍然是一个有点片状,因为有时你可能需要显式转换。我会考虑删除至少一个隐式转换运算符 - 可能会用明确的运算符(如果您的编译器支持这种情况)或命名函数(如string本身与c_str()一起)替换它们。

+0

它是Visual Studio 2012.CTP支持显式转换操作符。 – chris 2013-03-01 15:09:37

+0

@chris:看看我的评论sehe – alex555 2013-03-01 15:54:29

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); 
} 
+0

你应该改变C风格转换'操作符字符串( )') – 2013-03-01 15:05:38

+0

@ArneMertz好点 – sehe 2013-03-01 15:07:37

+0

嗯,你的修改产生了另外两个错误:'错误C2071:'A :: operator std :: string':非法的存储类'。似乎不喜欢明确... – alex555 2013-03-01 15:36:15

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)或者删除其中的一个。