auto a = A(3);
は、右辺のタイプがA
なので、A a = A(3);
と同じ意味です。
これは、それがどのように見える正確に何を意味:A(3)
は3
で初期化された一時的なA
を作成し、A a = _____
意味:初期化子として_____
とa
と呼ばれるA
を作成します。
一時的に作成し、a
に初期化子として渡してから一時的に破棄します。このタイプの初期化(=
)は、コピー初期化と呼ばれます(ただし、「コピー」と混同しないでください)。
コンストラクタは、A
を受け入れるa
を構築するように選択されます。これは、コピーコンストラクタまたは移動コンストラクタのいずれかでなければなりません。 A
には、移動コンストラクタとコピーコンストラクタがあります。後者は、ユーザーが宣言した移動コンストラクターが存在するため、暗黙的に生成され、削除済みとして定義されます。
削除されたとして定義されても、過負荷の解決には影響しません。この場合、コピーコンストラクタよりも移動コンストラクタが優先されます。
コードでdelete
d関数が呼び出されようとしています。そのため、エラーが発生します。
移動コンストラクタが削除されなかった場合は、コピーエリートが適用されます。変数が一時的なものから初期化される場合や、ローカル変数が値によって返される場合があります。規則は、コンパイラがa
と一時オブジェクトの両方に同じメモリを使用し、コピー/移動コンストラクタの呼び出しを省略することができます。
ほとんどの/すべてのコンパイラは、実際にこの状況でこれを実行します。したがって実際にはauto a = A(3);
と書くことができ、実際には不必要な動きはありません。あなたが何かを出力するあなたの移動コンストラクタ用のコードを書くなら、何も出力されていないことが分かります。
不必要なコピーがないことを絶対に確かめたい、または使用可能なコピーも移動コンストラクタもないオブジェクトを作成する場合は、不要なコピーを指定するコードの作成をやめてください! A a(3);
で十分です。
あなたの最初のコメントについて、私の印象は、これはしばしば "これは、通常は出てこない技術を除いて同じ"として紹介されているということです。しかし、多分私はOPの口に単語を入れています。 – Hurkyl
そのような人物を紹介する人は、無能に解雇されるべきです。 – Blindy
インテントが明確に同じ場合、コンパイラが異なるコードを生成するのはなぜですか?プログラマがその動作を望むケースはありますか? – Shmoopy