7

Wrapper2 つのテンプレート化された代入演算子のオーバーロードによって区別される単純な struct があります。

template<typename T>
struct Wrapper {

  Wrapper() {}

  template <typename U>
  Wrapper &operator=(const Wrapper<U> &rhs) {
    cout << "1" << endl;
    return *this;
  }
  template <typename U>
  Wrapper &operator=(Wrapper<U> &rhs) {
    cout << "2" << endl;
    return *this;
  }
};

次に、a と b を宣言します。

Wrapper<float> a, b;
a = b;

bへの割り当てaは、上記の非 const テンプレート割り当て演算子のオーバーロードを使用し、数字「2」が表示されます。

私を困惑させるのはこれです:私が and を宣言するcd

Wrapper<float> c;
const Wrapper<float> d;
c = d;

および assign dtocの場合、2 つの代入演算子のオーバーロードはどちらも使用されず、出力は表示されません。そのため、デフォルトのコピー代入演算子が呼び出されます。const オーバーロードされた代入演算子を使用dしないように代入するのはなぜですか? または代わりに、代入でデフォルトのコピー代入演算子を使用しないcのはなぜですか?ba

4

2 に答える 2

18

const オーバーロードされた代入演算子を使用dしないように代入するのはなぜですか?c

次のように宣言されている暗黙的に宣言されたコピー代入演算子は、引き続き生成されます。

Wrapper& operator=(const Wrapper&);

演算子テンプレートは、暗黙的に宣言されたコピー代入演算子の生成を抑制しません。引数 (const 修飾さWrapperれた ) は、この演算子 ( ) のパラメーターと完全に一致するため、const Wrapper&オーバーロードの解決中に選択されます。

演算子テンプレートは選択されておらず、あいまいさはありません。なぜなら、他のすべての条件が等しい場合、非テンプレートはテンプレートよりもオーバーロードの解決時に適しているからです。

代入がデフォルトのコピー代入演算子を使用bしないのはなぜですか?a

引数 (const 修飾されていないWrapper) はWrapper<U>&、暗黙的に宣言されたコピー代入演算子 ( を受け取るconst Wrapper<U>&.

于 2011-04-11T18:36:21.787 に答える
6

C++03 標準、§12.8/9 から:

ユーザー宣言のコピー代入演算子は、型、、、またはのパラメーターを 1 つだけ持つclassX::operator=の非静的非テンプレートメンバー関数です。XXX&const X&volatile X&const volatile X&

そして§12.8/10:

クラス定義でコピー代入演算子が明示的に宣言されていない場合は、暗黙的に宣言されます。

operator=yourがテンプレートであるという事実により、それはコピー代入演算子ではなくなります。そのため、クラスの暗黙的なコピー代入演算子はコンパイラによって引き続き生成されます。

于 2011-04-11T18:41:35.467 に答える