为什么这个例子中没有打印任何东西?我正在Coliru的Clang编译。为什么移动构造函数不被调用?
#include <iostream>
struct S
{
S() noexcept = default;
S(S&&) noexcept { std::cout << "move-ctor"; }
};
void f(S) {}
int main()
{
f(S{});
}
为什么这个例子中没有打印任何东西?我正在Coliru的Clang编译。为什么移动构造函数不被调用?
#include <iostream>
struct S
{
S() noexcept = default;
S(S&&) noexcept { std::cout << "move-ctor"; }
};
void f(S) {}
int main()
{
f(S{});
}
编译器执行复制省略,其每一段所允许的C++ 11标准的12.8/31,即使你的移动构造函数,复制构造函数,或析构有副作用:
当满足某些条件时,即使为复制/移动操作选择的构造函数和/或对象 的析构函数具有副作用,也允许实现省略类 对象的复制/移动构造。
术语复制省略使用,即使此举被省略掉:
复制/移动操作的这个省音,称为复制省略,允许在下列情况下(其中 可以组合以消除多个副本):
[...]
- 当未绑定到引用(12.2)的临时类对象将被复制/移动到具有相同cv不合格类型的类对象时,复制/移动操作可被 删除,构建临时对象直接进入副本省略的目标/移动
[...]
随着GCC,您可以使用-fno-elide-constructors
禁止复制省略。在这种情况下,您会看到移动构造函数被调用,如此live example。
如果我正在移动,为什么称为复制精简? – user2030677
@ user2030677:这是Standaldese的术语。主要是出于历史原因(在C++ 03中,只有副本可以被删除,因为移动语义不存在) –
@ user2030677您正在删除* copy *,这可能是使用复制构造函数或复制移动构造函数执行的。 – juanchopanza
[C++ 11移动构造函数未调用,首选默认构造函数]的可能重复(http://stackoverflow.com/questions/13099603/c11-move-constructor-not-called-default-constructor-首选) – jogojapan