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

时间:2011-09-17 18:40:30

标签: c++ copy move c++11 implicit

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

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

同样 move-assign ,使用相应的T operator=(T&&)元素。

示例:

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

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

班级Question

  • 将隐式声明 copy-constructor assign
  • 将隐式声明 move-constructor move-assign ,但它们将是=delete d ,因为非静态数据成员data_ 可复制,但无法移动

更新。一个附带问题:对于Question q; std::move(q)还会有效吗?复制的后备是否会在那里发生?或者隐式声明的 move-ctor会强制编译器因错误而停止吗? Here它确实编译。

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

1 个答案:

答案 0 :(得分:5)

你读错了。这会破坏许多C ++ 03类,例如以下

Question getQuestion();
Question q(getQuestion()); // use of deleted move constructor!

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

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

  

用于移动构造函数,非静态数据成员或直接或虚拟基类,其类型不具有移动构造函数,并且不易于复制。

在下文中,移动构造函数将被定义为已删除,因为CopyOnly不可轻易复制。

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

        Question(Question&&) = default;
 };