【发布时间】:2016-12-19 10:02:51
【问题描述】:
#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 rvalue ref 绑定到 non -const rvalue ref,但您可以将其绑定到 const 左值引用)。 -
你是什么意思,“如何避免复制?”。你问
vector::push_back(T &&)是怎么实现的? -
@SteveJessop,在某种程度上是的。但我最好不要详细说明。我的基本问题是,因为来自外部的
A&& a可能会在某个位置创建。std::vector是连续容器。怎么可能完全避免复制? -
@iammilind: 好吧,如果值类型
T是代码中的struct A,移动该类型与复制它完全相同,所以复制 isn '不避免。对于具有有用移动构造函数的类型(例如vector本身具有),它比复制构造函数的执行速度更快,那么我们就可以开展业务了。但是,如果一个类型将其所有数据存储在对象本身内部(即没有像vector这样的外部数据结构),那么一般来说,您无法编写有用的移动构造函数/赋值。 -
要记住的是Copyable这个概念是Movable概念的一个子集。可自动复制的所有东西也是可移动的,即使C++ 所指的移动实际上只是作为副本实现的。这就是为什么移动没有指定源处于什么状态的部分原因:允许它根本不改变它的状态。然而并非所有可移动的东西也是可复制的(例如
unique_ptr),并且对于某些可复制的东西,移动与复制不同(例如vector)。
标签: c++ c++11 reference language-lawyer move