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;
}

返回的错误是:

错误 C2440:“类型转换”:无法转换'CTestObj''std::wstring'
没有构造函数可以采用源类型,或者构造函数重载决议不明确

我已经意识到注释掉任何一个转换运算符都可以解决编译问题。我只想明白:

  1. 是什么导致了这个
  2. 为什么这在 VS2010 中编译而不在 VS2012 中编译?是因为 C++11 的变化吗?
4

1 回答 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;
}
于 2012-09-02T04:15:30.647 回答