隐式声明的移动操作不会回退到复制吗?
我读 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
类
- 将具有隐式声明的副本。 -构造函数和分配
- 将具有隐式声明的移动构造函数和移动分配,但它们将
=delete
d,因为非静态数据成员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
=delete
d, because the non-static data-memberdata_
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你读错了。在如下情况下,这会破坏许多 C++03 类 相反
,FDIS 表示将声明移动构造函数 iff {没有用户声明 {复制构造函数,{复制,移动} 赋值运算符,析构函数}并且隐式声明的移动构造函数不会被定义为已删除}。
关于更新2。我注意到,如果您显式默认移动构造函数,它将被定义为由条件删除
在下面,移动构造函数将被定义为已删除,因为
CopyOnly
不是普通可复制的。You read it incorrectly. This would break lots of C++03 classes in cases such as the following
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
In the following, the move constructor will be defined as deleted, because
CopyOnly
is not trivially copyable.