以下代码在Visual Studio 2010能够编译通过,但在Visual Studio 2012 RC中无法通过编译。
#include <string>
// Windows stuffs
typedef __nullterminated const wchar_t *LPCWSTR;
class CTestObj {
public:
CTestObj() {m_tmp = L"default";};
operator LPCWSTR() { return m_tmp.c_str(); } // returns const wchar_t*
operator std::wstring() const { return m_tmp; } // returns std::wstring
protected:
std::wstring m_tmp;
};
int _tmain(int argc, _TCHAR* argv[])
{
CTestObj x;
std::wstring strval = (std::wstring) x;
return 0;
}
出现的错误是:
error C2440: 'type cast' : 无法将
'CTestObj'
转换为'std::wstring'
源类型不存在构造函数,或构造函数重载决议存在歧义
我已经意识到注释掉任何一个类型转换操作符都可以解决编译问题。 我只是想了解:
- 底层发生了什么导致此错误
- 为什么在VS2010中可以编译,而在VS2012中不能?这是因为C++11的更改吗?
operator LPCWSTR
可能是一个不好的想法。如果你有一个函数CTestObj foo()
,那么这个操作符会默默地允许LPCWSTR x = foo();
,然后你现在就有了一个指向已释放内存的指针。 - jamesdlinCString
(和_bstr_t
)而言,这是一个多年存在问题的约定。在我看来,显式调用c_str()
方法的额外负担非常小,C++标准委员会之所以选择了c_str
路线而不是隐式转换路线是有原因的。(虽然现在使用C++11,显式转换操作符似乎是一个很好的折衷方案。) - jamesdlin