2013-06-01 75 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

相关问题