移动构造函数可以隐含吗?

Ben*_*enj 12 c++ visual-c++ move-semantics c++11 visual-studio-2012

考虑以下课程:

class A
{
public:
   std::string field_a;
   std::string field_b;
}
Run Code Online (Sandbox Code Playgroud)

现在考虑以下复制结构:

A a1(a2);
Run Code Online (Sandbox Code Playgroud)

A尽管缺少显式的复制构造函数,复制构造仍将充分复制,因为复制构造函数std::string将由编译器生成的隐式复制构造函数调用.

我想知道的是,移动建筑也是如此吗?

编辑:这里的测试表明:

A a2(std::move(a1));
Run Code Online (Sandbox Code Playgroud)

实际上会导致复制构造,除非特定的移动构造函数:

A( A && other ) : a(std::move(other.a)) {}
Run Code Online (Sandbox Code Playgroud)

被定义为.

编辑编辑 我谴责了Stephan T Lavavej,并问他为什么VC 2012似乎没有遵循12.8关于隐式移动构造函数生成的草案.他很友好地解释道:

它更像是一个"尚未实现的功能",而不是一个bug.VC当前实现了我所称的rvalue references v2.0,其中move ctors/assign永远不会隐式生成,并且永远不会影响copy ctors/assign的隐式生成.C++ 11指定了右值引用v3.0,这是您正在查看的规则.

rod*_*igo 9

是的,来自C++ 11草案,12.8:

如果类X的定义没有显式地声明一个移动构造函数,那么当且仅当一个移动构造函数被隐式声明为默认值时

  • X没有用户声明的复制构造函数,
  • X没有用户声明的复制赋值运算符,
  • X没有用户声明的移动赋值运算符,
  • X没有用户声明的析构函数,和
  • 移动构造函数不会被隐式定义为已删除.

后面的条件稍后详细说明:

隐式声明的复制/移动构造函数是其类的内联公共成员.如果X具有以下内容,则将类X的默认复制/移动构造函数定义为已删除(8.4.3):

  • 具有非平凡对应构造函数的变体成员,X是类似联合的类,
  • 类型M(或其数组)的非静态数据成员,由于应用于M的相应构造函数的重载解析(13.3),无法复制/移动,导致模糊或从默认情况下删除或无法访问的函数构造函数,
  • 直接或虚拟基类B无法复制/移动,因为重载解析(13.3),应用于B的相应构造函数,导致模糊或从默认构造函数中删除或无法访问的函数,
  • 任何直接或虚拟基类或具有析构函数的非静态数据成员,该析构函数已从默认构造函数中删除或无法访问,
  • 对于复制构造函数,rvalue引用类型的非静态数据成员,或
  • 对于移动构造函数,一个非静态数据成员或直接或虚拟基类,其类型没有移动构造函数,并且不是简单的可复制.

简而言之,如果符合以下情况,将隐式声明移动构造函数:

  1. 该类没有用户声明的任何其他特殊成员函数.
  2. 移动构造函数可以通过移动其所有成员和基础来合理地实现.

你的班级显然符合这些条件.


Die*_*ühl 5

如果可以,并且如果没有用户定义的复制构造函数,编译器将合成移动构造函数.如果存在复制构造函数则不合成移动构造函数的限制旨在避免破坏现有代码.当然,所有成员都需要移动.确切的规则涉及更多.