6

Il codice seguente viene compilato in Visual Studio 2010 ma non riesce a compilare in Visual Studio 2012 RC.Errore di compilazione C++ in Visual Studio 2012: LPCWSTR e 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; 
} 

L'errore riscontrato è:

errore C2440: 'cast di tipo': non può convertire 'CTestObj'-'std::wstring'
Nessun costruttore potrebbe prendere il tipo di sorgente, o la risoluzione di sovraccarico costruttore era ambigua

Mi sono già reso conto che commentare gli operatori di conversione risolve il problema di compilazione. Voglio solo capire:

  1. Quali 's sta succedendo sotto il cofano per causare questo
  2. Perché questo compila in VS2010 e non in VS2012? È a causa di una modifica del C++ 11?
+0

Uh, molto probabilmente si tratta di un bug ... – ildjarn

+0

Questo potrebbe essere il caso, ma la mia impressione è che è un cambiamento di rottura che io proprio non capisco. – jqcAngel

+2

Avere l'operatore "LPCWSTR" è probabilmente una cattiva idea. Se hai una funzione 'CTestObj pippo()', allora l'operatore ammette automaticamente 'LPCWSTR x = pippo();', e ora hai un puntatore alla memoria liberata. – jamesdlin

risposta

1

Se sto capendo la logica sotto il cofano, il sovraccarico dell'operatore sta cercando di copiare il codice e l'oggetto ogni volta che lanci. Pertanto, è necessario return it as a reference anziché tentare di restituire un nuovo oggetto in base al campo. La linea: dovrebbe essere

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

:

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

I seguenti compilato ed eseguito come previsto.

#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

Questo avrebbe dovuto avere risposta molto tempo fa. Le mie simpatie per così tanto tempo di attesa! – Qix

+1

E mi dispiace per aver impiegato così tanto tempo ad accettare questa risposta! Grazie mille. – jqcAngel

+0

Non un problema:] – Qix