在移动分配运算符方面移动构造函数
Move constructor in terms of move assignment operator
在我们项目的代码库中,我找到了类似的东西:
struct MeshData {
MeshData() {}
MeshData(MeshData&& obj) { *this = std::move(obj); }
MeshData& operator=(MeshData&& obj) {
if (this != &obj) {
indexes = std::move(obj.indexes);
}
return *this;
}
std::vector<int> indexes;
};
从移动分配方面实施移动构造对我来说似乎是一个聪明的想法,可以减少代码重复,但是在寻找信息后,我没有找到任何特别的建议。
我的问题是:这是 antpattern 还是在任何情况下不应该这样做?
如果您的类型具有没有默认构造函数的数据成员,则不能执行此操作,如果它们具有昂贵的默认构造函数,则不应执行此操作:
struct NoDefaultCtor {
NoDefaultCtor() = delete;
NoDefaultCtor(int){}
};
struct Foo {
Foo(Foo&& obj) { *this = std::move(obj); }
Foo& operator=(Foo&& obj) {
if (this != &obj) {
thing = std::move(obj.thing);
}
return *this;
}
NoDefaultCtor thing;
};
给出此错误:
<source>: In constructor 'Foo::Foo(Foo&&)':
<source>:10:20: error: use of deleted function 'NoDefaultCtor::NoDefaultCtor()'
Foo(Foo&& obj) { *this = std::move(obj); }
^
<source>:5:5: note: declared here
NoDefaultCtor() = delete;
这是因为必须在输入构造函数之前构建所有数据成员。
但是,最好的建议是遵循零的规则,避免写那些特殊成员。
当移动构造函数和成员变量的运算符可能产生不同的结果时,这种方法的陷阱之一就可以表现出来。例如,如果indexes
是使用std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value
评估true
的自定义分配器的CC_1,则会发生这种情况。在这种情况下,专用移动构造函数将同时移动分配器和数据而无需抛出异常时,在调用移动分配的同时将导致新的存储分配,并且所有项目移动构造,导致大量开销,并防止移动构造函数没有投掷。
相关文章:
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么调用复制构造函数而不是移动构造函数?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 移动构造函数和右值引用
- 为什么 std::memmove 中联合的默认非平凡移动构造函数C++?
- 具有专用化的模板类中的可靠条件复制和移动构造函数
- C++:为什么不调用移动构造函数?
- 移动构造函数永远不会被调用
- C++:关于使用 Stroustrup 示例移动构造函数/赋值的问题
- 运算符+ 的规范实现涉及额外的移动构造函数
- C ++为什么在移动构造函数中需要移动/前进
- 为什么在删除"移动构造函数"时使用"复制构造函数"?
- 为什么这里不调用移动构造函数?
- 隐式移动构造函数
- 如何为具有私有成员的派生类实现移动构造函数
- 为什么不调用移动构造函数
- 是否可以避免在以下代码中复制/移动构造函数的需要?