問題タブ [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.

0 投票する
6 に答える
9710 参照

c++ - C++ 戻り値の最適化

このコード:

ここでの私の誤った理解は、関数 getstdvec が実際に返すベクトルを割り当てる必要がないということです。これを valgrind/callgrind で実行すると、malloc への呼び出しが 1001 回あることがわかります。main の最初のベクトル宣言では 1、ループ反復ごとに 1000。

何を与える?毎回割り当てることなく、このような関数からベクトル (またはその他のオブジェクト) を返すにはどうすればよいですか?

編集:ベクトルを参照渡しするだけでよいことはわかっています。不必要な割り当てを発生させることなく、オブジェクトを返すこのような関数を作成することは可能である (さらには望ましいことである) という印象を受けました。

0 投票する
1 に答える
781 参照

c++ - コピー/移動省略と明示的に削除されたコピー/移動コンストラクター

copy/move elision が明示的にdeleted copy/move コンストラクターと非deleted copy/move コンストラクターにいつ適用されるか (または適用が許可されるか) を知りたいです。詳細は次のとおりです。

  1. 明示的にdeleted copy ctor または move ctor を省略できますか? 別の同じタイプのオブジェクトまたは一時オブジェクトからオブジェクトを構築しようとする試みは、deleted copy ctor および/またはdeleted move ctor をスキップすることによって成功することが許可されていますか?

    VC12で何が起こるかは次のとおりです(コピー/移動省略を無効にするオプションがあるかどうかはわかりません):

    IntelliSense はFoo{ Foo() };:について文句を言いますError: function “Foo::Foo(Foo &&)” ... cannot be referenced – it is a deleted functionが、コンパイラはそこで文句を言わないので、その行はまだコンパイルされます。

  2. なぜ機能するのに機能しFoo{ Foo() };ないのFoo{ std::move(f) };ですか? 1 つの呼び出しが move ctor を無視する場合、もう 1 つの呼び出しはすべきではありませんか?

  3. なぜ機能するのに機能しFoo{ Foo() };ないのFoo{ f };ですか? この選択性は恣意的に見えます。const 参照に対する右辺値参照 (またはその逆) のこの種の任意の設定は、非 ctor メソッドには適用されないようです。呼び出しで、deleteそうでなければ d 以外のオーバーロードよりも高いオーバーロード解決優先度を持つdeleted オーバーロードの場合、deleted は非 d のものをブロックdeleteし、コンパイラ エラーが発生します。

    その論理によれば、引数が一時的でない場合、 deletedFoo(Foo&&)は への呼び出しをブロックすべきではありません。その場合よりも過負荷解決の優先度が低くなります。Foo(Foo const&)Foo(Foo&&)Foo(Foo const&)

  4. Foog++ 4.8 でコピー省略を無効にして ( flag を介して)同じ例を試し、-fno-elide-constructors再度有効にしてみました。両方の g++ 試行で次の結果が得られました。

    error: use of deleted function 'Foo::Foo(Foo&&)'Foo{ Foo() };と_

    error: use of deleted function 'Foo::Foo(const Foo&)'為にFoo{ f };

    どのコンパイラが正しいですか?

0 投票する
1 に答える
927 参照

c++ - C++11 コンストラクター引数: std::move と value または std::forward と rvalue 参照

以下の 2 つのうちどちらを優先する必要がありますか。また、その理由は何ですか?

0 投票する
3 に答える
465 参照

c++ - 余分な移動をもたらす値渡し

移動のセマンティクスとコピー/移動の省略を理解しようとしています。

いくつかのデータをラップするクラスが欲しいです。コンストラクターでデータを渡したいのですが、データを所有したいと思います。

thisthis、およびthisを読んだ後、C++ 11 でコピーを保存する場合、値渡しは少なくとも他のオプションと同じくらい効率的である必要があるという印象を受けました (コードサイズの増加という小さな問題は別として) )。

次に、呼び出し元のコードがコピーを回避したい場合は、左辺値の代わりに右辺値を渡すことでできます。(例: std::move を使用)

だから私はそれを試しました:

出力:

これらのケースのいずれでもコピー コンストラクターが呼び出されないことを嬉しく思いますが、2 番目のケースで呼び出される余分な移動コンストラクターがあるのはなぜですか? まともな移動コンストラクターはDataかなり速いはずだと思いますが、それでも私はくすくす笑っています。代わりに右辺値参照渡し (最初のオプション) を使用したくなります。これにより、移動コンストラクターの呼び出しが 1 つ少なくなるように思われますが、可能であれば、値渡しとコピー省略を採用したいと考えています。

0 投票する
1 に答える
414 参照

c++ - リストの初期化とコピー省略

次の例を検討してください。

8.5.16 (C++11 標準の) によると、次の行

として扱われます

(つまり、タイプ A の一時オブジェクトが作成され、タイプ A の copy-ctor に渡されて x が初期化されます)。次に、12.8.31 に従って、コンパイラーはコピー省略」と呼ばれる最適化を実行して、型 A の一時的な作成を排除し、そのコード行を効果的に

(つまり、一時的に作成されず、copy-ctors が呼び出されません)。

ここで、上記の例で次のようにリストの初期化を使用するとします。

また

(1)および/または(2)が常に(つまり、コンパイラが「コピー省略」最適化を実行できる場合だけでなく)

(つまり、A の最初のコンストラクターが直接呼び出され、一時オブジェクトは作成されず、型 A のオブジェクトのコピーは実行されません)。

0 投票する
1 に答える
188 参照

c++ - コピーの省略と戻り値の最適化とコピー コンストラクターの比較

オブジェクト コピー コンストラクターの呼び出しを回避することで、Copy ellision と戻り値の最適化がどのように速度を向上させるかについて読んでいます。メカニズムがどのように機能するかは理解していますが、プログラムが期待どおりに動作しない可能性があるのではないかと思いました。

本質的に、私の質問は次のとおりです。別のオブジェクトのコピーであるオブジェクトを作成しないようにコピー コンストラクターを作成するとどうなりますか? 言い換えれば、

たとえば、次のようなクラスがあるとします。

これはクラスに入れるには明らかにひどい振る舞いです。私はこのようなことをすると言っているわけではありません。ただし、ポイントは有効です。コピーの副作用に頼っていたらどうなるでしょうか? この例では、作成したコピーの数を追跡します。最適化がプログラムの実行方法に影響を与えるべきではないと思います。ただし、コピーの省略により、次のコードが失敗する可能性があります。

これは、最適化なしでデバッグ モードでビルドすると 0 を返す可能性がありますが、最適化をオンにすると突然失敗し、MakeAClass からの戻り値がコピーに直接配置され、コピー コンストラクターがスキップされます。

コンパイラが副作用を探すためにこれらの最適化を試みるときのチェックはありますか? コピーを要求したときにコードがコピーを実行することを期待するのは間違っていますか?