2013-06-01 107 views
9

爲什麼這個例子中沒有打印任何東西?我正在Coliru的Clang編譯。爲什麼移動構造函數不被調用?

#include <iostream> 

struct S 
{ 
    S() noexcept = default; 
    S(S&&) noexcept { std::cout << "move-ctor"; } 
}; 

void f(S) {} 

int main() 
{ 
    f(S{}); 
} 
+0

[C++ 11移動構造函數未調用,首選默認構造函數]的可能重複(http://stackoverflow.com/questions/13099603/c11-move-constructor-not-called-default-constructor-首選) – jogojapan

回答

10

編譯器執行複製省略,其每一段所允許的C++ 11標準的12.8/31,即使你的移動構造函數,複製構造函數,或析構有副作用:

當滿足某些條件時,即使爲複製/移動操作選擇的構造函數和/或對象 的析構函數具有副作用,也允許實現省略類 對象的複製/移動構造。

術語複製省略使用,即使此舉被省略掉:

複製/移動操作的這個省音,稱爲複製省略,允許在下列情況下(其中 可以組合以消除多個副本):

[...]

- 當未綁定到引用(12.2)的臨時類對象將被複制/移動到具有相同cv不合格類型的類對象時,複製/移動操作可被 刪除,構建臨時對象直接進入副本省略的目標/移動

[...]

隨着GCC,您可以使用-fno-elide-constructors禁止複製省略。在這種情況下,您會看到移動構造函數被調用,如此live example

+0

如果我正在移動,爲什麼稱爲複製精簡? – user2030677

+1

@ user2030677:這是Standaldese的術語。主要是出於歷史原因(在C++ 03中,只有副本可以被刪除,因爲移動語義不存在) –

+0

@ user2030677您正在刪除* copy *,這可能是使用複製構造函數或複製移動構造函數執行的。 – juanchopanza

相關問題