問題タブ [nrvo]
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++ - std::optional 使用時の名前付き戻り値の最適化
std::optional
私は最近、特に関数の戻り値について、コードの明瞭さを改善する方法として発見しました。ただし、パフォーマンスへの影響については疑問がありました。より具体的には、コンパイラが名前付き戻り値の最適化を適用できるようにする、以下のようなコードを記述できるかどうかを知りたかったのです。
c++ - 演算子の戻り値に RVO を強制する方法は?
最後の 3 つのオペレーターで RVO を強制する方法:
プログラム実行出力:
またはstd::move
、最後の 3 つの演算子で明示的に使用する場合:
次のような演算子でコピーしたくない:
私がこれまでに考え出した唯一の方法は、演算子から参照を返すことですが、これは明らかにぶら下がり参照になります。
新しい g++ を使用して、c++14 および c++17 でコンパイルします。
アップデート
ルールを破ることなく、コンパイラに自分のやりたいことを強制することはできないことを理解しました。
しかし、コンパイラが右辺値をローカルで最適化するためにどのようなイベントが発生するのでしょうか? 次の追加で変更され、結果変数に割り当てられる最初の追加中に単一の右辺値を作成できると思います。
c++ - 削除されたコピーおよび移動コンストラクターを使用したコピー省略 (NRVO) は可能ですか?
cppreferenceでは、
オペランドが関数の戻り値の型と同じクラス型 (cv 修飾を無視) の prvalue である場合、コピー/移動コンストラクターは、return ステートメントに存在するか、またはアクセス可能である必要はありません。
私はこの権利を理解していますか? 上記の例を機能させるためには、少なくとも 1 つのコピーまたは移動コンストラクターを用意する必要がありますか?
私が試したことは次のとおりです。
このコードがコンパイルされて機能するのはなぜですか? 私の理解では、実際にはメソッド getEmptyPlayer() は、戻るときにオブジェクトをコピーするためにコピーコンストラクターを呼び出す必要があります。コンパイラによる効率の向上により、これは当てはまりませんが、コピー省略 (NRVO) が有効になり、オブジェクトを本来あるべき場所に直接構築し、コピーを作成しません。それにもかかわらず、cppreference (上記参照) は、アクセス可能または存在するコピー/移動コンストラクターが存在する必要があると述べています。では、ここで何が起こっているのでしょうか?
前もって感謝します!