2017-05-17 186 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(狗()),對象狗()被視爲一個R值(所以移動構造函數被調用),但以下兩行不會調用移動構造函數。我想我可能會誤解這裏的一個匿名對象和RValue之間的關係。

+1

查找RVO和NRVO,並將消息放入構造函數中,並添加一個帶有消息的析構函數(提示'c'和'd'可能正在就地構建)。如果你正在測試這種事情,那麼實現(和工具化)所有的構造函數(normal,copy,move)和析構函數是有用的。 –

+0

是的,它完全取決於RVO和NRVO。謝謝 –

回答

5

這是因爲Return Value Optimization。你的編譯器足夠聰明地看到,最後兩行可以簡化爲:

Dog c; 
Dog d; 

所以它被允許僅僅重寫你的代碼上面的代碼。由於push_back不符合允許RVO的要求,所以會創建一個臨時的,並且只是在您目擊的情況下移動。嘗試添加打印到構造函數,它會變得更清晰。

+1

啊,同樣努力瞭解來自微軟的比爾蓋茨來回答我的問題:)謝謝 –