自动生成带有不可移动成员的移动构造函数
Automatically generated move constructor with not movable members
我遇到了一种非常有趣的情况,因为我正在编译代码,尽管我很惊讶,所以我想问你的看法。
情况是这样的。我有一个带有删除的移动和复制构造函数的类,它具有用户定义的赋值操作符:
struct A {
A() { }
A(const A&) = delete;
A(A&& ) = delete;
A& operator=(const A& ) { return *this; }
A& operator=(A&& ) { return *this; }
};
我有另一个类,A
是唯一的成员。在本课程中,我定义了复制构造函数,但将move构造函数保留为默认值,并通过调用swap函数定义了赋值操作符:
class B{
public:
A a;
B()
: a{}
{ }
B(const B&)
: a{}
{ }
B(B&& other) = default;
};
int main() {
B b1;
B b2(std::move(b1)); // compiles??
}
为什么默认的移动构造函数可以工作,考虑到它不能简单地调用移动或复制构造函数A?
我原来的答案错了,所以我重新来过。
(班上
。Copy],我们有:
一个默认的副本/类X的move构造函数定义为deleted(8.4.3),如果X具有:
- - - - - -[…]
-一个潜在构造的子对象类型M(或其数组)不能被复制/移动,因为重载解析(13.3)应用于M的相应构造函数时,会导致歧义或a被删除或从默认构造函数
中无法访问的函数- - - - - -[…)
该要点适用于B(B&& other) = default;
,因此move构造函数被定义为deleted。这似乎会破坏std::move()
的编译,但我们也有(通过缺陷1402的解决方案):
定义为deleted的默认move构造函数被重载解析(13.3, 13.4)忽略。(注意:被删除的move构造函数会干扰右值的初始化,右值可以使用而是复制构造函数。
忽略是关键。因此,当我们这样做时:
B b1;
B b2(std::move(b1));
即使删除了B
的移动构造函数,这段代码仍然是格式良好的,因为移动构造函数根本不参与重载解析,而是调用复制构造函数。因此,B
是MoveConstructible——即使你不能通过它的move构造函数来构造它。
相关文章:
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么调用复制构造函数而不是移动构造函数?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 移动构造函数和右值引用
- 为什么 std::memmove 中联合的默认非平凡移动构造函数C++?
- 具有专用化的模板类中的可靠条件复制和移动构造函数
- C++:为什么不调用移动构造函数?
- 移动构造函数永远不会被调用
- C++:关于使用 Stroustrup 示例移动构造函数/赋值的问题
- 运算符+ 的规范实现涉及额外的移动构造函数
- C ++为什么在移动构造函数中需要移动/前进
- 为什么在删除"移动构造函数"时使用"复制构造函数"?
- 为什么这里不调用移动构造函数?
- 隐式移动构造函数
- 如何为具有私有成员的派生类实现移动构造函数
- 为什么不调用移动构造函数
- 是否可以避免在以下代码中复制/移动构造函数的需要?