6

以下代碼在Visual Studio 2010中編譯,但無法在Visual Studio 2012 RC中編譯。返回Visual Studio 2012中的C++編譯錯誤:LPCWSTR和wstring

#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的變化嗎?
+0

呃,最有可能的是這可能是這樣的一個錯誤...... – ildjarn

+0

,但我的預感是它,我只是不明白一個重大更改。 – jqcAngel

+2

無論如何,擁有'operator LPCWSTR'可能是一個壞主意。如果你有一個函數'CTestObj foo()',那麼操作符會默默地允許'LPCWSTR x = foo();',並且你現在有一個指向釋放內存的指針。 – jamesdlin

回答

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

這應該早就應答了。我對這樣漫長的等待時間表示同情! – Qix

+1

我很抱歉花了這麼長時間來接受這個答案!非常感謝。 – jqcAngel

+0

沒問題:] – Qix