可能的重复:
当向量增长时如何强制移动语义? https://stackoverflow.com/questions/8001823/how-to-enforce-move-semantics-when-a-vector-grows
insert
, push_back
and emplace
(_back
)可能会导致重新分配std::vector
。我很困惑地看到下面的代码copies的元素而不是moving他们在重新分配容器时。
#include <iostream>
#include <vector>
struct foo {
int value;
explicit foo(int value) : value(value) {
std::cout << "foo(" << value << ")\n";
}
foo(foo const& other) noexcept : value(other.value) {
std::cout << "foo(foo(" << value << "))\n";
}
foo(foo&& other) noexcept : value(std::move(other.value)) {
other.value = -1;
std::cout << "foo(move(foo(" << value << "))\n";
}
~foo() {
if (value != -1)
std::cout << "~foo(" << value << ")\n";
}
};
int main() {
std::vector<foo> foos;
foos.emplace_back(1);
foos.emplace_back(2);
}
在我的特定机器上使用特定编译器(GCC 4.7)打印以下内容:
foo(1)
foo(2)
foo(foo(1))
~foo(1)
~foo(1)
~foo(2)
但是,当删除复制构造函数时(foo(foo const&) = delete;
),生成以下(预期)输出:
foo(1)
foo(2)
foo(move(foo(1))
~foo(1)
~foo(2)
这是为什么?移动通常不会比复制更有效,或者至少不会比复制低很多吗?
值得注意的是GCC 4.5.1 做了预期的事情 http://ideone.com/2EPxu– 这是 GCC 4.7 中的回归,还是一些巧妙的优化,因为编译器发现我的对象复制起来很便宜(但如何复制?!)?
另请注意,我确保这is由重新分配引起,通过实验性地放置foos.reserve(2);
在插入的前面;这不会导致复制或移动被执行。