2012-11-04 105 views
0

我一直用C++ 11個移動語義移動語義行爲

在代碼中打轉轉......

#include <vector> 
#include <string> 

std::vector<std::string> GetNewVector() 
{ 
    std::vector<std::string> newVec; 
    newVec.push_back(std::string("hello")); //(1) 
    newVec.push_back(std::string("whey")); //(2) 

    return newVec; 
} 

int main(int argc, char* argv[]) 
{ 
    std::vector<std::string> vec = GetNewVector(); 
} 

在點(1)移動構造函數「 hello「對象在對象移入向量時調用。

在點(2)首先再次調用「hello」的移動構造函數(我假設這是vector重新分配的位置),然後調用「whey」移動構造函數。

這一切都如預期的那樣,但是我期待在GetNewVector()結束時返回矢量時再次移動對象,但移動構造函數不會再被調用。我的猜測是,RVO正在發生,但我在調試模式下運行Visual Studio(2k10)我不確定這是否會發生?

是不是真的,如果RVO可以執行,那麼它將優先於使用移動構造函數嗎?

+0

這是什麼語言? TString(CERN ROOT?)std :: vector無指定類型? –

+0

你有什麼是邏輯上的副本,而不是一個動作。爲了做到這一點,你必須做'返回std :: move(newVec)'。 –

+2

@VaughnCato:壞壞!在這裏使用'std :: move'會抑制RVO,並且標準已經說過,編譯器首先必須嘗試移動'newVec',並且只有在失敗時才複製它。 – Xeo

回答

6

如果指定它們按元素移動,則容器上移動的優點將嚴重受損。

取而代之的是,他們只是將其他內部的膽量,指向動態分配的數組的指針指向std::vector的情況,這會將元素保留在原來的位置,從而使其成爲一個持續複雜的操作。如果你做了元素式的移動,你會看到一個線性的複雜操作。

是不是真的,如果RVO可以執行,那麼它會優先於使用移動構造函數嗎?

該標準在這方面有點受限制,但是,RVO(通常是copy-elision,也包括與其名稱相反的動作)當然會優先於其他任何事情,因爲速度更快。 :)

請注意,自動移動只能在上下文中完成,其中副本刪除可能可以完成,但不是由於任何原因。有關自動移動的更復雜細節,另請參閱this question

+0

啊好吧,所以指向矢量內的原始數組的指針是簡單的複製?有道理,謝謝 – TomP89

+0

@ TomP89:好吧,複製,然後舊的指針設置爲空,所以當舊的向量超出範圍,它不會嘗試刪除數組。 :) – Xeo

+0

好的輝煌,感謝您的解釋 – TomP89