#include <vector>
struct A { int a[100]; };
void foo (const A& a) {
std::vector<A> vA;
vA.push_back(std::move(a)); // how does move really happen?
}
int main () {
A a;
foo(a);
}
以上代码编译正常。现在到处都写着move
可以避免复制。
以下是我的问题:
move
在处理左值[非]const
引用时是否真的有效?- 即使使用“右值引用”,当对象插入类似上面的标准容器时,如何避免复制?
例如
void foo (A&& a) { // suppose we invoke this version
std::vector<A> vA;
vA.push_back(std::move(a)); // how copy is avoided?
}
std::move(a)
产生一个const A &&
(请记住,std::move
仅将其参数转换为右值引用)。但是,并不存在push_back(const A &&)
--只有push_back(const A &)
和push_back(A &&)
--,并且将调用第一个,导致发生复制(因为您无法将const右值引用绑定到非const右值引用,但可以将其绑定到const左值引用)。 - peppevector::push_back(T &&)
吗? - Steve JessopA&& a
可能来自外部并在某个位置创建,而std::vector
是连续容器,如何完全避免复制? - iammilindT
是来自您的代码中的struct A
,那么移动该类型与复制它完全相同,因此并没有避免复制。对于具有有用的移动构造函数的类型(例如vector
本身),它可以执行比复制构造函数更快的操作,那么我们就可以使用它。但是,如果一个类型将其所有数据存储在对象本身内部(即没有像vector
那样的外部数据结构),那么一般而言,您无法编写有用的移动构造函数/赋值运算符。 - Steve Jessopunique_ptr
),而对于某些可复制的对象来说,移动和复制是不同的(例如vector
)。 - Steve Jessop