隐式声明的移动操作不会回退到复制

Implicitly-declared Move-Operations do not fallback to Copy?

本文关键字:回退 复制 操作 声明 移动      更新时间:2023-10-16

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

  • 在元素方面移动所有非静态数据成员的(可能通过分别定义的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_;
};

Question

  • 将隐式声明复制构造函数赋值
  • 将隐式声明move-constructormove-assign,但它们将是=delete d,因为非静态数据成员data_只有copyable,而不是movable?

更新。一个侧面问题:Question q;std::move(q)仍然工作吗?是否会出现倒退到复制的情况?或者隐式声明的移动动作会强制编译器停止并出现错误吗?

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

你读错了。在以下情况下,这会破坏许多c++ 03类:

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

相反,FDIS说,如果没有用户声明的{复制构造函数,{copy, move}赋值操作符,析构函数},并且隐式声明的move构造函数不会被定义为删除},则将声明move构造函数。

关于更新2。我注意到,如果您显式默认move构造函数,它将被定义为被条件

删除。

用于move构造函数,非静态数据成员或直接基类或虚基类,其类型没有move构造函数,并且通常不具有可复制性。

在下文中,move构造函数将被定义为删除,因为CopyOnly不是一般的可复制的。

 struct Question 
 {
        std::vector<int> data_;
        CopyOnly         copyOnly_;
        Question(Question&&) = default;
 };