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

发布于 2024-12-05 06:23:57 字数 1241 浏览 1 评论 0原文

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

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

,同样移动- 。分配,使用元素各自的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

  • 将具有隐式声明的副本。 -构造函数分配
  • 将具有隐式声明的移动构造函数移动分配但它们将=deleted,因为非静态数据成员 data_ 可复制,但不可可移动

更新。一个附带问题:对于Question q;std::move(q)仍然有效吗?那里会发生回退复制吗?或者隐式声明的 move-ctor 会强制编译器因错误而停止吗? 这里它确实可以编译。

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

Do I read N3291 "12.8.(11/15/28) Copying and moving class objects class.copy]" correct that the implicitly-declared move constructor

  • does an element-wise move of all non-static data-members (probably via respectively defined T(T&&)
  • and if any non-static data-member can not be moved, the implicit move-constructor will be marked as deleted and not tried to be copied as a "fallback"? (yes, move is defined for built-in types, but actually is a copy).

and likewise the move-assign, using the respective T operator=(T&&) of the elements.

Example:

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

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

The class Question

  • will have implicitly-declared copy-constructor and assign
  • will have implicitly-declared move-constructor and move-assign, but they will be =deleted, because the non-static data-member data_ is only copyable, but not movable?

Update. A side-question: For Question q; will std::move(q) still work? Will the fallback to copy happen there? Or will the implicitly-declared move-ctor force the compiler to stop with an error? Here it does compile.

Update 2. What does the compiler generate for the non-movable data-members if I declare the move-ctor Question(Question&&) =default? Does it then fallback to copying those?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光无声 2024-12-12 06:23:57

你读错了。在如下情况下,这会破坏许多 C++03 类 相反

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

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

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

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

在下面,移动构造函数将被定义为已删除,因为CopyOnly 不是普通可复制的。

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

        Question(Question&&) = default;
 };

You read it incorrectly. This would break lots of C++03 classes in cases such as the following

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

Instead, the FDIS says that a move constructor will be declared iff {there is no user declared {copy constructor, {copy, move} assignment operator, destructor} and the implicitly declared move constructor would not be defined as deleted}.

Regarding Update 2. It has been brought to my attention that if you explicitly-default the move constructor, it will be defined as deleted by the condition

for the move constructor, a non-static data member or direct or virtual base class with a type that does not have a move constructor and is not trivially copyable.

In the following, the move constructor will be defined as deleted, because CopyOnly is not trivially copyable.

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

        Question(Question&&) = default;
 };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文