编译器何时不生成移动构造函数和移动赋值?

Posted

技术标签:

【中文标题】编译器何时不生成移动构造函数和移动赋值?【英文标题】:When does compiler not generate move constructor and move assignment? 【发布时间】:2017-12-14 17:10:14 【问题描述】:

在Effective Modern C++中,它说

移动操作仅针对缺少显式的类生成 声明了移动操作、复制操作和析构函数。

但我用 Gcc 和 Clang 测试过,没有抛出任何错误。那么这条规则已经过时了吗?

Example program:

#include <iostream>
#include <string>
#include <vector>
#include <memory>

class A

    int i;
    public:
    ~A() = default;
;

int main()

    A a, b;
    a = b;
    A c(a);
    A d(std::move(a));
    b = std::move(d);

编辑:从书中复制了“移动操作”,这可能会导致混淆。将其更改为移动构造函数和移动赋值。

【问题讨论】:

让我们从基础开始。什么是移动操作 编译器会在语言规定的时候生成它们,除非它是错误的。 std::move 不移动,就像std::forward 不转发,std::remove 不删除和delete 不删除它的操作数:) @ChristianHackl - 也被称为“有史以来最好的名字” @StoryTeller:是的,好吧,只是std::prepare_for_movestd::prepare_for_forwardstd::shuffle_around_in_order_to_removedelete_object_pointed_to_by 会更糟:) 【参考方案1】:

std::move 只是对A&amp;&amp; 的转换。它创建的相同 xvalue 将愉快地绑定到 const A&amp;,这是隐式默认的复制 c'tor 和复制赋值运算符所接受的。所以这就是你所说的。

您“出现”到std:move 的事实并不意味着已定义任何这些移动操作。

如果您在班级中添加A(A&amp;) = default;,则内容将开始以红色下划线显示。因为现在复制 c'tor 接受非 const 左值引用,它不会绑定到 A&amp;&amp;

【讨论】:

"红色下划线?"我想这取决于您的编译模式设置和终端。通常,GCC 不会因此修饰其错误消息(也许 Clang 会?) @TobySpeight - 这是对 OP 的神螺栓链接的引用。

以上是关于编译器何时不生成移动构造函数和移动赋值?的主要内容,如果未能解决你的问题,请参考以下文章

自动生成默认/复制/移动 ctor 和复制/移动赋值运算符的条件?

C++类的默认函数

[C++11 类的改进] --- 继承控制:=default和=delete

移动构造函数和移动赋值与拷贝构造函数和赋值构造函数的比较

c++类的构造函数不显式声明会自动生成吗

移动构造函数和移动赋值函数