2016-03-23 6 views
4

我々は、すべてのFooのコピーコンストラクタが副作用を持っている場合でも値のコピーが取られないように新しい変数を導入して戻り値の最適化を無効にしますか?

Foo returnAFoo() 
{ 
    return Foo(); 
} 

が戻り値の最適化でコンパイルされますことを知っています。しかしwill

Foo returnAFoo() 
{ 
    Foo f = Foo(); 
    return f; 
} 

too? 2番目の構文は、デバッグ時に役立ちます。しかし、私はそうすることで重要な最適化を捨てていますか?おそらく私は明示的な移動コンストラクタを書く必要がありますか?

+1

注意*名前付き*戻り値最適化(NRVO)と呼ばれる戻り値最適化の特定の変形があります。通常の「RVO」よりも難しい場合もありますが、一般的にはコンパイラが実行できます。両方ともオブジェクトを動かすこととはまったく異なります。明示的なコピーコンストラクタ/代入演算子を持っている場合は、明示的に移動コンストラクタ/代入演算子も定義する必要があります。 – BoBTFish

+0

@BoBTFish:答えとしてそれを入れてください:私はそれを受け入れます。 –

+1

http://cpp.sh/9yvs –

答えて

7

いいえ、ここでもコピーエリシジョンを適用できます。この特定のケースでは、NRVO(戻り値最適化)と呼ばれます。コピー・エリジョンを実行するための移動コンストラクタは必要ありません。 copy elisionは、コピーコンストラクタのみを持っていたC++ 98/03以降、標準になっています。

すべてのコードパスが同じオブジェクト(NRVO)を返すか、すべてのコードパスが一時オブジェクト(RVO)を返すかを確認する必要があります。

同じ関数内でNRVOとRVOを混在させて一致させると、最適化を適用するのが難しくなります。


Sample code NRVOを示す。

関連する問題