3

GCC 4.6 では、ムーブ コンストラクターによって子の代入演算子が暗黙的に削除された場合でも、親の代入演算子を継承できます。GCC (および Clang) の新しいバージョンでは、これはもはや不可能です。子クラスに親の代入演算子を使用させる適切な方法は何ですか?

struct A
{
  A & operator=(A const & other) = default;
};

struct B : public A
{
  B() {}
  B(B && other) {}

  using A::operator=;
};

int main()
{
  B b1, b2;
  b1 = b2; // error: use of deleted function because B's operator= is implicitly deleted due to move constructor
  return 0;
}
4

2 に答える 2

2

派生型をそれ自体に割り当てるときに何をしたいかによって異なります。move 演算子が暗黙的な生成を抑制しているにもかかわらず、子代入演算子を「通常の」ように動作させたい場合は、次のようにして子代入をクラスに戻すことができます。

    B &operator=( B const & ) = default;

これはおそらく、GCC 4.6 が行ったことと同等です。GCC 4.6 では、生成された演算子が標準で要求されているように適切に抑制されていないと思います。そのため、using 宣言が引き込まれた基本クラスからのオーバーロードと共に、通常の代入演算子の動作が得られたのでしょう。

実際にクラスの基本部分のみを割り当てたい場合は、独自の割り当て演算子を実装する必要があります。

    B &operator=( B const &that ) {
        static_cast<A&>(*this) = that;
        return *this;
    }

残念ながら、今すぐ試す GCC 4.7 はありませんが、派生クラスで実際に基本クラスの代入演算子を取得していても驚かないでしょうが、派生クラスの削除された代入演算子は、あなたの例により適しています. main() で次の行を試すことで、これをテストできます。

    b1 = static_cast<A const&>(b2);

于 2013-04-01T22:22:56.010 に答える