重複の可能性:
コンストラクターの署名を移動する
struct X
{
X(X&); // (1)
X(X&&); // (2)
X(const X&); // (3)
X(const X&&); // (4)
};
(4)
オーバーロードの解決で選択される状況はありますか?
重複の可能性:
コンストラクターの署名を移動する
struct X
{
X(X&); // (1)
X(X&&); // (2)
X(const X&); // (3)
X(const X&&); // (4)
};
(4)
オーバーロードの解決で選択される状況はありますか?
はい。const
1 つの状況は、戻り値を持つ関数がある場合です。
const X f();
X x(f());
別の状況は、次の例のようにstd::move
、オブジェクトに適用する場合です。const
#include <iostream>
using namespace std;
struct X
{
X() { cout << "default" << endl; }
X(X&) { cout << "non const copy" << endl; } // (1)
X(X&&) { cout << "non const move" << endl; } // (2)
X(const X&) { cout << "const copy" << endl; } // (3)
X(const X&&){ cout << "const move" << endl; } // (4)
};
void f(X const x)
{
}
int main()
{
X const x;
f(std::move(x));
return 0;
}
前の回答 ( X const f()
) で言及されたケースは、おそらくあまり一般的ではありません。これは、ほとんどの場合、RVO を実行するときに移動コンストラクターがコンパイラーによって省略されるためです (これは、コンストラクターに副作用がある場合でも実行できます)。
論理演算としてconst
オブジェクトを別のconst
オブジェクトに移動することは理にかなっています。移動コンストラクターを定義しないと、それを行うことはできません。移動は所有権を譲渡するだけなので、論理的な操作としてサポートする必要があるように思えます。const
高レベルの観点から、オブジェクトを変更することは想定されておらずconst
、実際にオブジェクトを移動するにはオブジェクトを変更する必要があることは事実ですが (ほとんどの場合)、const
オブジェクトを変更しても問題ないという同様の状況がよく知られています。より高いレベルの概念的な操作を実現することを目的として、シーン" 。const
非 const メンバー ミューテックスをロックする必要があるメンバー関数のインスタンスを考えてみましょうmutable
。非 const オブジェクトとして扱うようにミューテックス変数を宣言できます。
したがって、この場合でも、移動されたオブジェクトのメンバーconst
を変更するための移動コンストラクターでの正当な操作 (必要な限り) と見なしmutable
ます (おそらく、オブジェクトのデストラクタによってチェックされるブールフラグ)。const
上記のコードからコンストラクター (3) と (4)を削除すると、コンパイルされないことに注意してください。const
(4) のみを削除すると、コピー コンストラクター (3) が選択されます。つまり、オブジェクトを移動することはできません。