编译器何时不生成移动构造函数和移动赋值?
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_move
、std::prepare_for_forward
、std::shuffle_around_in_order_to_remove
和delete_object_pointed_to_by
会更糟:)
【参考方案1】:
std::move
只是对A&&
的转换。它创建的相同 xvalue 将愉快地绑定到 const A&
,这是隐式默认的复制 c'tor 和复制赋值运算符所接受的。所以这就是你所说的。
您“出现”到std:move
的事实并不意味着已定义任何这些移动操作。
如果您在班级中添加A(A&) = default;
,则内容将开始以红色下划线显示。因为现在复制 c'tor 接受非 const 左值引用,它不会绑定到 A&&
。
【讨论】:
"红色下划线?"我想这取决于您的编译模式设置和终端。通常,GCC 不会因此修饰其错误消息(也许 Clang 会?) @TobySpeight - 这是对 OP 的神螺栓链接的引用。以上是关于编译器何时不生成移动构造函数和移动赋值?的主要内容,如果未能解决你的问题,请参考以下文章
自动生成默认/复制/移动 ctor 和复制/移动赋值运算符的条件?