6

はのは、私が機能を持っているとしましょう:C++ 0xの戻り値はrvalue参照で渡されますか?

typedef std::vector<int> VecType; 
VecType randomVector(); 

int processing() 
{ 
    VecType v = randomVector(); 
    return std::accumulate(v.begin(), v.end(), 0); 
} 

C++ 0xのは、具体的スプリアスコピーがrandomVectorの戻り値から回避されると言っていますか?あるいは、コンパイラはRVOを実装する必要がありますか? randomVector()の値がrvalueとして扱われ、vのmoveコンストラクタが呼び出されるはずですが、これが本当であるかどうかは完全にはわかりません。コンパイラはRVOを行うことができる場合

+0

良い質問ではありません、IMHO。標準では、実装が何をしているのか、それがしなければならないことだけを有用に述べることはできません。 –

+0

実際、戻り値最適化を指定した例では、ほとんどのコンパイラで最適化が行われています...したがって、それは右辺値なしで有効です。 引数を関数に渡すためには、rvalueが重要です。 – Artyom

+0

質問のタイトルは少し誤解を招く。あなたの関数はrvalueを返しますが、参照は返しません。しかし、rvalue参照はそれにバインドすることができます。何らかの理由でコピーエリミッションを実行できず、型に移動コンストラクタがある場合(移動コンストラクタのパラメータはrvalue参照です) – sellibitze

答えて

7

ルールが

  • 以下である、それを行うには許可され、何のコピーなし移動は行われません。
  • それ以外の場合は、適切なコンストラクタが使用されます。

あなたが言うように、一時的にため右辺値参照は左辺値参照右辺値よりも良いと結合することを言います13.3.3.2/3内のルール、の、右辺値であるため、移動コンストラクタが選択されています。移動コンストラクタかコピーコンストラクタのどちらを使用するかを決定するには、オーバーロード解決が移動コンストラクタを優先させます。

コンパイラがRVOを実行できるルールは、12.8/15に書き込まれます。

2

すべての戻り値はrvaluesと見なされます。したがって、コンパイラーがRVOを実装していない場合は、コピーコンストラクターではなく移動コンストラクターを使用する必要があります。

+1

"移動を使用しなければならない"と解釈する。 1)RVOに優しい場合は、移動/コピー操作を最適化します。 2)elseコンストラクタを使用できる場合は、 を使用します。3)その他の場合はコピーします。使用できるコンストラクタは です。それ以外は不正なプログラムです。 – mloskot

+0

@mloskotコピーコンストラクタよりもオーバーロードに適しているので、移動コンストラクタが選択されています。 – Motti

+2

入手しました。動いているctorが存在するという暗黙の仮定は私には不明であった。移動先が選択されていますが、存在する場合にのみ選択されます。 – mloskot

関連する問題