C++ 11では、暗黙的な生成が自動的に防止されている場合、特別なメンバー関数を明示的にデフォルトすることができます。明示的にデフォルトの特別なメンバー関数の生成を実施する
しかし、特別なメンバ関数を明示的にデフォルトにすると、他の特別なメンバ関数(コピー操作、デストラクタなど)のいくつかを手動で宣言することによる暗黙の削除のみが元に戻ります。機能が実際には生成できない場合でも、コードは適切に形成されているとみなされます。
次のシナリオを検討してください:
struct A
{
A() = default;
A (const A&) = default;
A (A&&) = delete; // Move constructor is deleted here
};
struct B
{
B() = default;
B (const B&) = default;
B (B&&) = default; // Move constructor is defaulted here
A a;
};
そうすることは、コンパイル・エラー(Aの動きコンストラクタが削除された)を引き起こすため、Bに移動コンストラクタは、コンパイラによって生成されることはありません。 Aのコンストラクタを明示的に削除しなければ、Bの移動コンストラクタは期待通りに生成されます(移動するのではなく、Aをコピーします)。そのようなオブジェクトを移動しようとすると、
は黙っ代わりにコピーコンストラクタを使用します。
B b;
B b2 (std::move(b)); // Will call B's copy constructor
は、関数を生成するか、それができない場合は、コンパイル・エラーを発行するのいずれかにコンパイラを強制する方法はありますか?この保証がないと、削除された単一のコンストラクタがオブジェクト階層全体の移動を無効にできる場合、デフォルトの移動コンストラクタに依存することは困難です。
あなたが含まれているメンバーが移動可能であるかどうかは分かりませんか? – NathanOliver
クラスが最初に実装されたときにそれらは移動可能ですが、後でメンバーが追加されると、移動可能な要件が見落とされる可能性があります(特に、他のメンバーによって追加された場合)。 –
移動コンストラクタを削除しますが、コピーコンストラクタを削除しないタイプは非常に奇妙です。これを行うことによって得られるべきことは全くありません。だからこそ、この事件を無視するのが最善の方法かもしれません。なぜなら、誰かが何の理由もなくばかげたことをした結果であると考えているからです。 –