2016-02-15 16 views
7

クラスの移動コンストラクタを無効にしたいとします。移動するのではなく、コピーコンストラクターをベースにしたいと思います。私はこのコードを記述しようとすると:コンパイル時に移動コンストラクタを無効にする

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
    Boo(Boo&& boo) = delete; 
}; 

Boo TakeBoo() 
{ 
    Boo b; 
    return b; 
} 

を私はエラーを受け取っ:

error C2280: 'Boo::Boo(Boo &&)': attempting to reference a deleted function

は、どのように私の代わりに移動コンストラクタと力のコピーを無効にすることができますか?

+6

はちょうど移動コンストラクタをオーバーロードしていないと、すでに標準からコピーコンストラクタ –

+2

があるので、コンパイラはそれのための移動のコンストラクタを生成しません:「クラスXの定義は明示的に宣言されていない場合移動コンストラクタは、Xがユーザ宣言されたコピーコンストラクタを持たない場合にのみデフォルトとして暗黙的に宣言されます[...]移動コンストラクタが暗黙的に宣言されていないか明示的に指定されていない場合、コンストラクタは代わりにコピーコンストラクタを呼び出すことができます。 – Pixelchemist

+1

これで何を達成したいですか?それは意味があるようには思えません。 –

答えて

17

任意の移動のコンストラクタを作成しないでください:

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
}; 

移動コンストラクタが自動的に限り、コピーコンストラクタが呼び出されるように、ユーザー定義のコピーコンストラクタが存在しているように生成されていません。

+6

コピーコンストラクタが存在する場合、moveコンストラクタは自動的に生成されません*。これはOPの例の場合ですが、読者が移動コンストラクタを実装していないと移動を回避するのに十分ではないと結論づけないように、指摘する価値はあります。たとえば、2つの 'std :: vector'メンバを持ち、暗黙的に定義されたコピーまたは移動コンストラクタを持たないクラスは、ベクトルを移動する自動生成移動コンストラクタを取得します。 – user4815162342

4

関数を=deleteとマークすると、関数はオーバーロードの解決に使用できますが、選択するとコンパイルは失敗します。この機能はコンストラクタやその他の特殊機能に限定されません(see here)。以前は(circa C++ 03)メンバーを非公開にしても同様の結果が得られました。

したがって、サンプルのコードは、一時的または期限切れの値(rvalues) - 移動コンストラクタからクラスのオブジェクトの構築を禁止することを意味します。

これを修正するには、移動コンストラクタを完全に削除します。クラスの場合、コピーコンストラクターが存在する(ユーザー定義)と、移動は暗黙的には何も生成されません(コンストラクターの移動と代入演算子の移動)。

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
    //Boo(Boo&& boo) = delete; 
}; 
+2

追加情報:自分自身を削除したとして移動コンストラクタをマークすると、実際にはオーバーロード解決に利用できるようになります。ただし、ムーブコンストラクタが暗黙的に削除されていると定義されている場合(メンバ変数の移動コンストラクタが暗黙的または明示的に削除されて定義されている場合など)、オーバーロード解決には使用できません。 (過負荷の解像度は楽しいです...) –

関連する問題