强制复制分配优于移动分配运算符

Jon*_*ove 6 c++ move copy-constructor move-constructor

假设我有一个定义了复制和移动赋值运算符的对象。当我写下这个:

Object a(/*parameters 1*/);
/* some code */
a = Object(/*parameters 2*/);
Run Code Online (Sandbox Code Playgroud)

第三行很可能会调用移动赋值运算符。如何强制编译器使用复制赋值?相关地,如何强制复制移动构造函数?基本上我要求反向 std::move()

我为什么想要这个?

第 1 行和第 3 行之间的代码(我无法更改)获取一些指向 的字段的指针,即重要的是,不改变 的a内存布局(移动最有可能做的事情),而是用新值覆盖。a

此外,我的对象只是std::vector. 当我移动分配它时,编译器只会将其底层数组的指针重定向到右值向量的数组。当我复制分配它时(并且之前的向量a更长),那么它的底层数组将被覆盖,但它们的地址将保持不变。不幸的是,“某些代码”存储了像 之类的指针&a[2],并且它们可能不会改变。

眠りネ*_*ネロク 2

左值传递给赋值运算符

一种方法是将左值而不是右值传递给要分配给的对象的赋值运算符:

Object a(/*parameters 1*/);
Object b(/*parameters 2*/);
// ...
a = b; // <-- b is an lvalue, copy not move
Run Code Online (Sandbox Code Playgroud)

这样,将选择 的a复制赋值运算符。


将不可移动的对象限定为const

另一种方法是const限定您不想移动的对象。即使您有一个std::move()已经在使用的赋值,这也有效,因为const- 限定对象不会绑定到右值引用。因此,不会选择移动赋值运算符。那是:

const Object b(/*parameters 2*/);
// ...
a = std::move(b); // <-- still copies, b is const
Run Code Online (Sandbox Code Playgroud)

即使b上面明确标记为使用std::move(b),a的复制赋值运算符进行移动。