2017-05-17 19 views
1

私は右辺値参照を理解するために、この例で遊んでいた:参照はいつRvalue参照ですか?

#include <string> 
#include <iostream> 
#include <utility> 
#include <vector> 

class Dog 
{ 
public: 
    Dog() {}; 
    Dog(Dog&& a) { std::cout << "R value" << std::endl;} 
}; 

Dog foo() 
{ 
    return Dog(); 
} 

int main() 
{ 
    std::vector<Dog> v; 
    v.push_back(Dog()); // calls move constructor 

    Dog c((Dog())); // does not call move constructor 
    Dog d(foo()); // does not call move constructor 
} 

私はラインv.push_back(ドッグ())、オブジェクト・ドッグ()で右辺値として扱われている理由を理解するために苦労(そう移動コンストラクタが呼び出されます)が、次の2行は移動コンストラクタを呼び出しません。ここでは、匿名オブジェクトとRValueとの関係を誤解している可能性があります。

+1

RVOとNRVOをルックアップしてメッセージをコンストラクタに入れ、メッセージとともにデストラクタを追加します(ヒント 'c'と' d'はおそらくインプレースで構築されています)。このようなことをテストしている場合は、すべてのコンストラクタ(normal、copy、move)とデストラクタを実装(および計測)すると便利です。 –

+0

はい、それは完全にRVOとNRVOです。ありがとう –

答えて

5

Return Value Optimizationのためです。だから、ちょうど上記のコードにコードを書き換えを許可され

Dog c; 
Dog d; 

:あなたのコンパイラは、最後の2行はに単純化することができることを確認するために十分スマートです。 push_backはRVOが許可されている要件を満たしていないため、一時的なものが作成され、あなたが目撃したときに単純に移動します。コンストラクタにプリントを追加すると、より明確になります。

+1

ああ、マイクロソフトのビル・ゲイツが私の質問に答える方法を理解するのにも苦労しています:)ありがとう –

関連する問題