1

カスタム クラスを、VS2005 で非常によくコンパイルされる文字列にキャストしたいと考えています。しかし、VS2012 ではコンパイラ エラーが発生しますerror C2440: 'type cast' : cannot convert from 'A' to 'std::string'。何を変更する必要がありますか? これは私の例です:

    #include <string>

    using namespace std;

    class A
    {
    public:
      A& operator=(const char* c);
      operator string ();
      operator const char* ();

    private:
      string value;
    };

    A::operator string () { return string((const char*)(*this)); }
    A& A::operator = (const char* aValue)   { value = aValue; return *this; }
    A::operator const char *() { const char* wort = "Hello"; return wort; }

    int main() 
    {
      A a;
      string s = (string)a; // C2440
    }
4

3 に答える 3

3

問題は、Ato からstring- への変換演算子を介したstring;への 2 つの明示的な変換が考えられることです。または、変換演算子をconst char *介して へ、次に変換コンストラクターを介して へstring

単純に変換を暗黙的にすることで、あいまいさが解決されます。2 番目の変換には 2 つのユーザー定義の変換が必要なため、暗黙的な変換には選択できません。

string s = a;

ただし、明示的な変換が必要になる場合があるため、クラスはまだ少し不安定です。少なくとも 1 つの暗黙的な変換演算子を削除することを検討します。おそらく、それらを明示的な演算子 (コンパイラがそのようなものをサポートしている場合) に置き換えるか、名前付き関数 (stringそれ自体が で行うように) に置き換えますc_str()

于 2013-03-01T15:03:54.390 に答える
1

変換があいまいです。

C スタイルのキャストは避け、変換を明示的にすることを好みます。

#include <string>

using namespace std;

class A
{
public:
  A& operator=(const char* c);
  explicit operator string ();
  explicit operator const char* ();

private:
  string value;
};

A::operator string () { return string(static_cast<const char*>(*this)); }
A& A::operator = (const char* aValue)   { value = aValue; return *this; }
A::operator const char *() { const char* wort = "Hello"; return wort; }

int main() 
{
  A a;
  string s = static_cast<std::string>(a);
}
于 2013-03-01T15:03:14.190 に答える
0

2 つの変換演算子が互いに足を踏み入れます。それらのそれぞれは、暗黙的な変換に対して機能します。ただし、明示的なキャストはコンストラクターの直接呼び出しに似ています。あなたのコードで

string s = (string)a;

と同等です

string s = static_cast<string>(a);

次のようなものに変換されます

string tmp(a);
string s(std::move(tmp)); // this move can be elided
// lifetime of tmp ends here

核心は直接の初期化string tmp(a)です。2 つの実行可能な文字列コンストラクターがあります。 string(const string&)andexplicit string(const char *)と 2 つの変換により、どちらかを呼び出すことができます。どちらの変換シーケンスも優れていないため、呼び出しはあいまいです。

ちなみに、明示的なキャストなしでコピーの初期化を使用するバージョンはあいまいではありません。

string s = a;

動作するはずです。それによっては非常にもろくなるので、お勧めしません。

変換演算子を作成するexplicitか (C++11 を使用している場合)、そのうちの 1 つを削除する必要があります。

于 2013-03-01T15:12:57.463 に答える