2016-10-05 38 views
1

我在生命週期結束之前將一些對象傳遞給構造函數。爲什麼移動比通過const&?更加昂貴?

int main(){ 

    //I wanted to avoid short string optimization in this example. 
    const std::string a(25,"a"); 
    const std::string b(25,"b"); 
    const std::string c(25,"c"); 

    Foo f{a,b,c}; 
} 

我爲Foo的構造函數考慮了兩個選項。

const&(調用字符串的拷貝構造函數):

Foo(const std::string & a, 
    const std::string & b, 
    const std::string & c) 
:a(a) 
,b(b) 
,c(c) 
{} 

std::move(調用字符串的移動構造函數):

Foo(std::string a, 
    std::string b, 
    std::string c) 
:a(std::move(a)) 
,b(std::move(b)) 
,c(std::move(c)) 
{} 

隨着-01gcc 7,我得到了以下結果:

+-------------+-----------------------+ 
| constructor | assembly instructions | 
+-------------+-----------------------+ 
| const&  |     192 | 
| move  |     264 | 
+-------------+-----------------------+ 

爲什麼是const&減指令?
我認爲一個舉動會比通過複製構造函數創建一個新字符串便宜。

什麼是作爲構造函數參數傳遞變量的經驗法則
當這些參數的生命週期結束?

+2

從'main'中的'a,b,c'中刪除'const'和參數;並在函數調用中使用'move' –

回答

5

你沒有調用移動構造函數。你的參數字符串是const。所以當你使用std::move時,結果是const std::string&&。這不會調用移動構造函數,誰的簽名需要std::string&&

+0

我的錯誤。我*是*沒有const的調用。傳遞值和使用移動的結果相同。 –

0

如果編譯器不會使構造函數的一個特殊版本的主打電話,然後main仍在調用函數與簽名Foo(std::string a, std::string b, std::string c);

除非內聯,或GCC使得它的克隆,實際上以不同的方式傳遞參數,函數的定義中的代碼無法改變它的調用方式。

想象一下,構造函數的定義是在一個單獨的文件中,而在編譯main時,甚至不可見,只有原型。這與僅編譯-O1時得到的結果類似。