問題タブ [copy-elision]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - copy-elision を実行している間、コンパイラは、move コンストラクターが削除されると、オーバーロードの解決でコピー コンストラクターを考慮しません。なんで?
コピーおよび移動コンストラクターがいわゆるdone in で呼び出されないため、コンパイラーが以下のコードでコピー省略を行っていることを理解できます。実際の例を参照してください。copy-initialization
main()
しかし、以下のように移動コンストラクターを削除すると、コードがコンパイルされない理由がわかりません。
§12.8/32 (N4140) には、この場合、コピー コンストラクターの使用または省略を禁止するものは見つかりません。これは、§12.8/32 で私の注意を喚起した文であり、オーバーロードの解決でコピー コンストラクターを考慮する必要があることを示しているようです。
最初のオーバーロードの解決が失敗したか実行されなかった場合、または選択されたコンストラクターの最初のパラメーターの型がオブジェクトの型への右辺値参照 (おそらく cv 修飾) でない場合、オブジェクトを左辺値。
編集
以下のTCによるコメントの 1 つから、コピーされるオブジェクトが右辺値で指定されている場合、コンパイラは、§12.8/32 に従って、コピー コンストラクターをコピーの候補と見なさないことを理解しています。とにかくコピーは省略されますが。つまり、最終結果はs
、デフォルトのコンストラクターを使用したオブジェクトの構築になります。代わりに、この状況では、標準は (どこで??) コードの形式が正しくないことを義務付けています。このスキームに対する私の理解が完全に間違っていない限り、それは私には意味がありません。
c++ - 以下に示すスニペットで移動コンストラクターが省略されていない特別な理由はありますか?
gcc、 clang 、および VS2015 は、 object をスローした後、以下のコードの move コンストラクターへの呼び出しを省略しませんa
。§8.12[class.copy]/31 (N4140) の箇条書き (31.2) で確立された条件が満たされているように思えます。
は左辺値ですa
が、§12.8/32 に従って、オブジェクトが右辺値によって指定されているかのように、コピーのコンストラクターを選択するためのオーバーロード解決が最初に実行されます。つまり、move コンストラクターの呼び出しは問題ありません。上記のムーブ コンストラクターの定義を消去すると、コピー コンストラクターが呼び出されますが、省略されていません。
コピー省略が標準で義務付けられていないことは理解していますが、上記の 3 つのコンパイラがこの特定の例でこの最適化を回避しているという事実を正当化できる特別な条件があるかどうか知りたいです。
上記のリンクからの gcc の出力例:
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
デフォルトのセクター
移動先
デストラクタ
つかまった
デストラクタ
c++ - Is this code well-defined regardless of copy elision?
Consider this code:
One would expect an output like this:
and this is indeed what I get. But due to copy elision, could out
be in the same place in memory as in
and result in the last line of output being x: 2, y: 2
?
I've tried compiling with gcc and clang with both -O0
and -O3
, and the results still look as intended.
c++ - 値渡し引数のコピー省略
与えられた
実行するとしますBox box(Range(0.0,1.0),Range(0.0,2.0))
。
最適化が有効になっている最新のコンパイラは、Range
この構築中にオブジェクトを完全にコピーすることを回避できますか? (つまり、最初にRange
内部のオブジェクトを構築しますbox
か?)
c++ - これらのコピーを実際に削除するコンパイラはありますか?
与えられた
誰かが、コンパイラは最初からオブジェクトを内部で構築することにより、オブジェクトを完全にBox box(Range(0.0,1.0),Range(0.0,2.0))
コピーすることを避けることができると言いました。Range
box
実際にこれを行うコンパイラはありますか?
私自身の試みは成功していません。