下面是一些无法编译的代码,因为 push_back 试图调用已删除的 MoveOnlyClass 中的复制构造函数:
class MoveOnlyClass
{
public:
MoveOnlyClass() {};
MoveOnlyClass& operator=(const MoveOnlyClass& other) = delete;
MoveOnlyClass(const MoveOnlyClass& other) = delete;
};
int main()
{
std::vector<MoveOnlyClass> vec;
vec.push_back(std::move(MoveOnlyClass()));
}
为什么会这样?当然,vector 唯一应该调用的是 move 构造函数。将对象 move 到 vector 中的正确方法是什么?
最佳答案
删除复制构造函数/复制赋值函数也会隐式删除 move 构造函数/move 赋值函数。如果您打算使对象可 move 但不可复制,您还需要默认
move 构造函数。
class MoveOnlyClass
{
public:
MoveOnlyClass() {};
MoveOnlyClass& operator=(const MoveOnlyClass& other) = delete;
MoveOnlyClass(const MoveOnlyClass& other) = delete;
MoveOnlyClass& operator=(MoveOnlyClass&& other) = default;
MoveOnlyClass(MoveOnlyClass&& other) = default;
};
//Will now compile as you expect
int main()
{
std::vector<MoveOnlyClass> vec;
vec.push_back(std::move(MoveOnlyClass()));
}
此外,std::move(T())
是多余的;像这样就地构建对象已经使它成为 R 值,并且在不需要时使用 std::move
可能会阻止某些类型的编译器优化(例如 Copy Ellision)。
关于c++ - 为什么使用 std::vector::push_back 的 move 变体会调用 move 项的复制构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52429636/