最近、「c++ のオブジェクト モデルの内部」を読んでいて、第 5 章を読んでいるときに、次の質問を思いつきました。
クラスにコピー コンストラクターがある場合でも、コンパイラーは NRVO を処理しますか?
最近、「c++ のオブジェクト モデルの内部」を読んでいて、第 5 章を読んでいるときに、次の質問を思いつきました。
クラスにコピー コンストラクターがある場合でも、コンパイラーは NRVO を処理しますか?
答えは「いいえ、防げません」です。
n3290 (C++11 ドラフト)、Book of 12、第 8 章、31 節 (p284):
特定の基準が満たされている場合、オブジェクトのコピー/移動コンストラクターおよび/またはデストラクタに副作用がある場合でも、実装はクラス オブジェクトのコピー/移動構築を省略できます。
RVO (または NRVO) は、コンパイラがコピーを削除するために使用する最適化です。つまり、冗長なコピーが作成されるのを防ぎます。コピー コンストラクターのカスタム実装は、この最適化の適用を妨げることはできません。
RVO は多かれ少なかれ、代わりに別のスコープでオブジェクトを作成し、変数の読み取りまたは書き込み時にローカル オブジェクトの代わりにそのオブジェクトを使用します。これにより、オブジェクトが 1 つだけ作成され、copy ctor がまったく呼び出されず、無関係であると宣言したかどうかがレンダリングされます。
あなたの質問は「単純なコピーコンストラクターがnrvoを防ぐかどうか」だと思いますが、私の答えはノーです。本の「C++オブジェクトモデル内」のケースを使用し、foo関数とメイン関数のメンバーのアドレスを出力させます。結果は、リリースモードでは同じですが、デバッグモードでは異なることを示していますvs2010での楽観主義。つまり、NRVO は、重要なコピー コンストラクターがあるかどうかを気にしません。