0

誰かがキャストのルールを説明できますか、そして変換があいまいな場合は?MSVC ++(Visual Studio 2010)とgcc-4.3.4で異なる答えを与える次のケースに少し混乱しています。

#include <string>

class myStr
{
  std::string value;

public:
  myStr(const char* val) : value(val) {}
  operator const char*() const {return value.c_str();}
  operator const std::string() const {return value;}
};

myStr byVal();
myStr& byRef();
const myStr& byConstRef();

int main(int, char**)
{
  myStr foo("hello");
  std::string test;

  // All below conversions fail "ambiguous overload for 'operator='" in gcc
  // Only the indicated coversions fail for MSVC++
  test = foo;  // MSVC++ error "'operator =' is ambiguous"
  test = static_cast<std::string>(foo);

  test = byVal();  // MSVC++ error "'operator =' is ambiguous"
  test = static_cast<std::string>(byVal());  // MSVC++ error 
             // "'static_cast' : cannot convert from 'myStr' to 'std::string'"

  test = byRef();  // MSVC++ error "'operator =' is ambiguous"
  test = static_cast<std::string>(byRef());

  test = byConstRef();  // MSVC++ error "'operator =' is ambiguous"
  test = static_cast<std::string>(byConstRef());

  return 0;
}

これらの変換のどれが合法であるかを管理するルールは何ですか?そして、との両方へmyStrのキャストを定義するようなクラスを明確に使用するための準拠した方法はありますか?const char*const std::string

4

1 に答える 1

2

との両方をstd::string取る代入演算子がオーバーロードされているため、暗黙の変換はすべてあいまいです。これは、両方の変換演算子が等しく適切な選択であることを意味します。したがって、あいまいさは次のとおりです。const std::string&const char*

myStr -> std::string -> operator=(const std::string&)
myStr -> const char* -> operator=(const char*)

のあいまいさstatic_castは、キャストを使用して一時std::stringオブジェクトを作成しているためです。std::stringaまたはaのいずれかから作成することも同様に有効であるconst char*ため、ここでも両方の変換演算子が考慮されます。

myStr -> std::string -> static_cast<std::string>(std::string)
myStr -> const char* -> static_cast<std::string>(const char*)

代わりに参照にキャストすることで、あいまいさを解消できます。

test = static_cast<const std::string&>(foo);

変換演算子はオブジェクトを返すため、これでも一時的なものが作成されます。ただし、その変換は暗黙的に行われるようになったため、複数のユーザー定義の変換を含めることはできません。したがって、それはあなたを介してのみ行うことができ、operator std::string()あいまいさはありません。

myStr -> std::string -> static_cast<const std::string&>(std::string)
myStr -> const char* -> std::string -> static_cast<const std::string&>(std::string)
      ^^             ^^  two implicit user-defined conversions - not allowed

const不要な一時的なものを回避できるように、変換演算子を変更して参照を返すことも検討してください。

于 2012-06-27T13:09:33.260 に答える