隐式声明的Move-Operations不会回退到Copy?

tow*_*owi 6 c++ copy move implicit c++11

我读过N3291"12.8.(11/15/28)复制和移动类对象class.copy]"纠正隐式声明的移动构造函数

  • 做所有非静态数据成员的元素移动(可能通过分别定义T(T&&)
  • 如果无法移动任何非静态数据成员,隐式移动构造函数将被标记为已删除,并且不会被尝试复制为"后备"?(是的,move是为内置类型定义的,但实际上是副本).

同样,移动分配,使用各自T operator=(T&&)的元素.

例:

struct CopyOnly {
    CopyOnly();
    CopyOnly(const CopyOnly&);
}; // declaring a copy means no implicit move.

struct Question {
    std::vector<int> data_;
    CopyOnly         copyOnly_;
};
Run Code Online (Sandbox Code Playgroud)

班级 Question

  • 将具有隐式声明的复制构造函数赋值
  • 将有隐式声明的移动构造函数布展分配,但他们将被=delete,因为非静态数据成员data_可复制,但不移动

更新.可以侧面的问题:对于Question q;std::move(q)仍然有效?复制的后备是否会在那里发生?或者隐式声明的 move-ctor会强制编译器因错误而停止吗?在这里它编译.

更新2.如果我声明move-ctor,编译器为不可移动的数据成员生成什么Question(Question&&) =default?是否然后退回到复制那些?

Joh*_*itb 5

你读错了.在以下情况下,这会破坏许多C++ 03类

Question getQuestion();
Question q(getQuestion()); // use of deleted move constructor!
Run Code Online (Sandbox Code Playgroud)

相反,FDIS表示将声明移动构造函数iff {没有用户声明{copy constructor,{copy,move}赋值运算符,析构函数}并且隐式声明的移动构造函数不会被定义为已删除 }.

关于更新2.我注意到,如果你明确地默认移动构造函数,它将被条件定义为删除

对于移动构造函数,一个非静态数据成员或直接或虚拟基类,其类型没有移动构造函数,并且不是简单的可复制.

在下文中,移动构造函数将被定义为已删除,因为CopyOnly它不是简单的可复制的.

 struct Question 
 {
        std::vector<int> data_;
        CopyOnly         copyOnly_;

        Question(Question&&) = default;
 };
Run Code Online (Sandbox Code Playgroud)