3

コピーコンストラクターが削除されたクラスがあるとします。

struct NoCopy
{
    NoCopy(int) {}
    NoCopy(const NoCopy &) = delete;
};

このクラスを別のクラスで使用します。

struct Aggregate
{
    NoCopy nc;
};

しかし、集計の初期化を使用しようとすると

int main()
{
    Aggregate a{3};
}

コンパイラは次のエラーを出力します。

error: use of deleted function ‘NoCopy::NoCopy(const NoCopy&)’

集約の初期化にクラスのメンバーのコピー コンストラクターが必要なのはなぜですか? 集計の初期化は、コピー コンストラクターを使用してすべてのメンバーを初期化しますか?

4

1 に答える 1

7

必要なものの正しい構文は次のとおりです。

Aggregate a{{3}};

これにより、NoCopyメンバーの初期化子が提供されます。余分なものがなければ、{}コンパイラは から への変換を実行する必要がintありNoCopy(非明示的なコンストラクタを介して喜んで行います)、それを使用して を構築しncます。これは通常、move 構築として発生しますが、copy ctor を削除することにより、move コンストラクターも効果的に削除されます。

これについて考える簡単な方法NoCopyは、値コンストラクターが 1 つではなく 2 つの引数を取ることを想像することです。

struct NoCopy {
    NoCopy(int, int);
};

今あなたが書いたなら

Aggregate a{1, 2};

1これは、が初期化に使用され、他の何かを初期化するために使用されnc2いることを示します (コンパイル時エラー)。{}これを理解するには、余分なものを追加する必要があります

Aggregate a{{1, 2}};

3 番目の方法では、関数呼び出しを調べます。

struct NoCopy {
  NoCopy(int) {}
  NoCopy(const NoCopy &) = delete;
};

void fun(NoCopy) { }

int main() {
  fun(1); // wrong
  fun({1}); // right
}

この// wrongバージョンでは、コンストラクターを使用して呼び出しサイトで一時NoCopyオブジェクトが構築されNoCopy(int)ます。次に、そのテンポラリは値によって に渡されますがfunNoCopyコピーできないため失敗します。

バージョンでは、// right構築する引数の初期化リストを提供しています。コピーは作成されません。

于 2015-12-19T08:20:27.057 に答える