2016-12-03 8 views
7

のは、我々はこのような状況にこの状況でRVOが適用されていますか?

std::string v_1() 
{ 
    return "name"; 
} 
std::string test = v_1(); 

があるとしましょうRVOは、ここで適用されていますか? RVOを適用するルールの1つが「」であるため、答えは「いいえ」と考えられます。関数が値によってクラスタイプを返し、returnステートメントの式が自動記憶期間を持つ非揮発性オブジェクトの名前である場合、isn関数の戻り値の型と同じ型(最上位のcv-qualificationを無視する)を持つをコピーしてコピー/移動を省略した場合 " この状況では返されるオブジェクトには関数の戻り値の型と同じ型はありませんが、ここでRVOが適用されていないことは100%ではありません。

ありがとうございました。

PS。この話ではhttps://www.youtube.com/watch?v=AKtHxKJRwp4(分40秒18)MicrosoftのStephanは、関数の戻り値の型が返されたオブジェクトの型と異なるため、RVOを適用できない状況について説明しています(この例ではタプル対)。私は同じ原則がここに当てはまると思います。

+3

ほとんどの場合、 'return std :: string(" name ")'に相当します... – Jarod42

+0

返されるのは 'const char *'ではありません... – user268396

+0

@ user268396ケース(これも)暗黙的に1に変換されてから文字列に変換されます:) –

答えて

5

NRVORVOを混同していると思います。

  • NRVO - 名前戻り値の最適化
  • RVO - RVOreturn文で構成され、無名の一時を必要とするのに対し、(名前)戻り値の最適化

NRVOという名前の変数を必要とします。

映像上の例が関数のスタック内のいずれかのタイプのオブジェクトが存在しなければ、別のためのタイプが異なる場合名前付きオブジェクトは明らか発信者スタック上に構築することができないNRVOあります呼び出し元のスタック上の他の型のオブジェクト

例は、事前に構築された名前付きオブジェクトを使用していないRVOです。あなたのコードでは、オブジェクトを戻り値として構築しています。 のため、引用したルールは適用されません。私はRVOが発生しないことができない理由見ないC++11標準によると

12.8のコピーをしてクラスを移動する[ class.copy ] オブジェクト... ...

- バウンスされていない一時クラスオブジェクトdを参照(12。2)コピーされる/同じCV-非修飾型のクラスオブジェクトに を移動、コピー/移動操作を省略コピーの標的に直接、一時的なオブジェクトを構築 によって省略することも可能/移動

char arrayを返すことによって、std::stringが構築され、というが呼び出し元に返されます。

3

NRVOとRVOは異なる溶出の場合です。

複数のオブジェクトの有効期間が1つのオブジェクトにマージされます。

NRVOとRVOという名前は、標準で許可されているときにコンパイラがどのように溶出するかの名前です。

return行に作成されたテンポラリ、関数の戻り値、戻り値を格納する名前付き変数の間では、すべての深刻なコンパイラがこれらの値を一緒に削除できます。明示的にそれをコンパイラフラグを介して指示しないでください。そして、C++では、これらの要素が必須となります。

関連する問題