1 に答える
削除された移動メンバーは悪です。いつか誰かがそれらの巧妙な使い方を見つけるので、それらは違法ではありません. しかし、私はまだ良い使い方を見たことがありません。
特別会員を削除することは、特別会員を持っていないことと同じではありません。これは、ムーブ コンストラクターとムーブ代入演算子ほど明らかです。
存在する場合、削除、デフォルト、またはユーザー定義のいずれであっても、ムーブ コンストラクターとムーブ代入演算子はオーバーロードの解決に参加します。つまり、特殊なコピーメンバーと「競合」するということです。通常、copy メンバーは const 左辺値を優先しますが、move メンバーは右辺値を引き付けます。
関数からローカル型を返す場合 (ローカル型が戻り値の型と同じ cv 修飾されていない型である場合)、return ステートメントは最初に戻り式を右辺値と見なします。コンストラクターは、左辺値と見なされますか。つまり、関数からローカル オブジェクトを返すための適切なコンストラクターの照合は、2 フェーズの操作です。
移動コンストラクターがまったくない (削除されていない) が、通常のコピー コンストラクターがある (const & を取る) 場合、return ステートメントの右辺値はコピー コンストラクターと一致します。
移動コンストラクターがある場合、それが削除済みとマークされていても、return ステートメントの右辺値は、移動コンストラクターがコピー コンストラクターよりも適切に一致することを検出します。
概要
自分が何をしているのか本当によくわかっていない限り、ムーブ メンバーを決して削除しないでください。型を移動可能にしたくない場合は、move メンバーを定義せず、copy メンバーが=default
'd であっても、必ず copy メンバーを宣言してください。
アップデート
削除が行わないことについて、標準からの引用を提供するのは難しいと思いますか? -DyP
8.4.3 削除された定義 [dcl.fct.def.delete]
2 削除された関数を宣言する以外に、暗黙的または明示的に参照するプログラムは形式が正しくありません。[ 注: これには、暗黙的または明示的に関数を呼び出すこと、および関数へのポインターまたはメンバーへのポインターを形成することが含まれます。潜在的に評価されない式の参照にも適用されます。関数がオーバーロードされている場合、関数がオーバーロードの解決によって選択されている場合にのみ参照されます。— エンドノート]
更新 2
12.8 クラスオブジェクトのコピーと移動 [class.copy]
9 クラス X の定義が移動コンストラクターを明示的に宣言しない場合、1 つがデフォルトとして暗黙的に宣言されます。
- X にはユーザー宣言のコピー コンストラクターがありません。
- X には、ユーザー宣言のコピー代入演算子がありません。
- X にユーザー宣言の移動代入演算子がなく、かつ
- X には、ユーザー宣言のデストラクタがありません。
[注: ムーブ コンストラクターが暗黙的に宣言されていないか、明示的に提供されていない場合、ムーブ コンストラクターを呼び出す式は、代わりにコピー コンストラクターを呼び出すことができます。— エンドノート]