在Visual Studio 2012中编译C++代码时出现错误:LPCWSTR和wstring。

6
以下代码在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'
源类型不存在构造函数,或构造函数重载决议存在歧义

我已经意识到注释掉任何一个类型转换操作符都可以解决编译问题。 我只是想了解:

  1. 底层发生了什么导致此错误
  2. 为什么在VS2010中可以编译,而在VS2012中不能?这是因为C++11的更改吗?

嗯,很可能是一个错误... - ildjarn
可能是这样,但我的直觉告诉我这是一个我不理解的破坏性变更。 - jqcAngel
2
拥有operator LPCWSTR可能是一个不好的想法。如果你有一个函数CTestObj foo(),那么这个操作符会默默地允许LPCWSTR x = foo();,然后你现在就有了一个指向已释放内存的指针。 - jamesdlin
@jamesdlin,这是微软的CString多年来一直使用的惯例,理论上的问题远远被日常便利所超越。 - Mark Ransom
1
@MarkRansom:我不同意“运行良好”的说法。在我看来,对于CString(和_bstr_t)而言,这是一个多年存在问题的约定。在我看来,显式调用c_str()方法的额外负担非常小,C++标准委员会之所以选择了c_str路线而不是隐式转换路线是有原因的。(虽然现在使用C++11,显式转换操作符似乎是一个很好的折衷方案。) - jamesdlin
1
你可以通过删除赋值来简化这个复制过程,只需使用“((std::wstring) x);”进行转换并丢弃结果。只有在暗示的情况下才会存在歧义。由于你明确地进行了转换,所以不应该存在歧义。请从VS2012的帮助菜单中提交错误报告给微软: - Dan
1个回答

1
如果我理解底层的逻辑,运算符重载试图在每次强制转换时复制代码和对象。因此,你需要将其作为引用返回,而不是基于字段尝试返回新对象。该行代码为:
operator std::wstring() const { return m_tmp; }

应该是:

operator std::wstring&() { return m_tmp; }

以下代码编译并运行正常。

#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&() { return m_tmp; }     // returns std::wstring

protected:
    std::wstring m_tmp;
};


int main()
{
    CTestObj x;
    std::wstring strval = (std::wstring) x;
    wprintf(L"%s\n", strval.c_str());

    return 0;
}

这个问题早就应该得到解答了。对于如此长时间的等待,我深表同情! - Qix - MONICA WAS MISTREATED
1
对不起,我花了这么长时间才接受这个答案!非常感谢。 - jqcAngel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接