假设我有一个对象,它同时定义了复制和移动赋值运算符。当我写下这段代码时:
第三行最可能调用移动赋值运算符。如何强制编译器使用复制赋值而非移动赋值?同样地,如何强制复制覆盖移动构造函数?我基本上是在寻求一个反向的std::move()。
为什么我想要这个呢?
1到3行之间的代码(我不能更改)获取了一些指向a字段的指针,因此a的内存布局不被改变很重要(这可能是移动所做的),而是被新值覆盖。此外,我的对象只是std::vector。当我移动分配它时,编译器将仅将其底层数组的指针重定向到rvalue向量的数组。当我复制分配它时(并且以前的向量a更长),那么它的底层数组将被覆盖,但它们的地址将保持不变。 "某些代码"不幸地存储像&a [2]这样的指针,它们可能不会改变。
Object a(/*parameters 1*/);
/* some code */
a = Object(/*parameters 2*/);
第三行最可能调用移动赋值运算符。如何强制编译器使用复制赋值而非移动赋值?同样地,如何强制复制覆盖移动构造函数?我基本上是在寻求一个反向的std::move()。
为什么我想要这个呢?
1到3行之间的代码(我不能更改)获取了一些指向a字段的指针,因此a的内存布局不被改变很重要(这可能是移动所做的),而是被新值覆盖。此外,我的对象只是std::vector。当我移动分配它时,编译器将仅将其底层数组的指针重定向到rvalue向量的数组。当我复制分配它时(并且以前的向量a更长),那么它的底层数组将被覆盖,但它们的地址将保持不变。 "某些代码"不幸地存储像&a [2]这样的指针,它们可能不会改变。
a
的布局或位置不能被改变,只能改变其成员的值。 (“移动”实际上并没有移动任何东西,而std::move
只是一种转换。) - molbdniloa
的布局,它只会将新值移动到相应的位置,这正是您想要的吧? 移动和复制的区别在于数据的源是否更改。 - gctauto a = std::vector{1, 2, 3}; auto b = &a[0]; a = std::vector{1, 2};
,在将a
移动后,b
将不再指向a[0]
。但是,如果保留了a
的存储空间(类似于std::vector
的复制构造函数,但仅当存储空间不必增加时),则b
仍然有效。我认为这就是这个问题想要表达的内容? - hegel5000/* some code */
,以便我们更好地了解在移植时可能会出现的问题? - 463035818_is_not_a_numberstd::unique_ptr<T[]>
的一个用例。这样你就可以保证指针不会改变。 - super