6

次のコードはVisualStudio2010でコンパイルされますが、Visual Studio2012RCではコンパイルできません。

#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. なぜこれはVS2012ではなくVS2010でコンパイルされるのですか?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 に答える