我想将一个自定义类强制转换为在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
}
答案 0 :(得分:3)
问题在于,从A
到string
有两种可能的显式转换 - 通过转换运算符转换为string
;或通过转换运算符const char *
,然后通过转换构造函数转到string
。
简单地隐藏转换将解决模糊性;第二次转换需要两次用户定义的转换,因此无法选择进行隐式转换:
string s = a;
但是,该类仍然有点不稳定,因为有时您可能需要显式转换。我会考虑删除至少一个隐式转换运算符 - 可能用显式运算符替换它们(如果你的编译器支持这样的东西),或用命名函数替换它们(比如string
本身用c_str()
)。< / p>
答案 1 :(得分: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);
}
答案 2 :(得分: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)或删除其中一个。