【问题标题】:C++ Compile Error in Visual Studio 2012: LPCWSTR and wstringVisual Studio 2012 中的 C++ 编译错误:LPCWSTR 和 wstring
【发布时间】:2012-06-06 06:11:26
【问题描述】:

以下代码在 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 的变化吗?

【问题讨论】:

  • 呃,很可能是一个错误......
  • 可能是这样,但我的直觉是这是一个我不明白的重大变化。
  • 拥有operator LPCWSTR 可能是个坏主意。如果你有一个函数CTestObj foo(),那么操作员会默默地允许LPCWSTR x = foo();,你现在有一个指向释放内存的指针。
  • @MarkRansom:我不同意“工作得很好”。 IMO 这是一个多年来一直困扰着CString(和_bstr_t)的惯例。 IMO 显式调用 c_str() 方法的额外负担非常低,并且 C++ 标准委员会确实采用了 c_str 路由而不是隐式转换路由是有原因的。 (尽管现在使用 C++11,explicit 强制转换运算符似乎是一个很好的折衷方案。)
  • 您可以通过删除分配来稍微简化此重现。只需使用“((std::wstring) x);”。投射它并丢弃结果。有歧义 IF 且仅当它被暗示时。由于您是明确铸造的,因此不应有歧义。请向 MS 提交错误:您可以从 VS2012 的帮助菜单中执行此操作。

标签: c++ visual-studio-2010 visual-c++ wstring visual-studio-2012


【解决方案1】:

如果我理解幕后的逻辑,则运算符重载会在您每次转换时尝试复制代码和对象。因此,您需要return it as a reference 而不是尝试根据该字段返回一个新对象。行:

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-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-12
  • 2013-03-22
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
相关资源
最近更新 更多