Possible Duplicate:
How to enforce move semantics when a vector grows?
insert
, push_back
and emplace
(_back
) can cause a reallocation of a std::vector
. I was baffled to see that the following code copies the elements instead of moving them while reallocating the container.
#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);
}
On my specific machine using my specific compiler (GCC 4.7) this prints the following:
foo(1)
foo(2)
foo(foo(1))
~foo(1)
~foo(1)
~foo(2)
However, when deleting the copy constructor (foo(foo const&) = delete;
), the following (expected) output is generated:
foo(1)
foo(2)
foo(move(foo(1))
~foo(1)
~foo(2)
Why is that? Would’t moving generally be more efficient, or at least not much less efficient, than copying?
It bears noting that GCC 4.5.1 does the expected thing – is this a regression in GCC 4.7 or is it some deviously clever optimisation because the compiler sees that my object is cheap to copy (but how?!)?
Also note that I made sure that this is caused by reallocation, by experimentally putting a foos.reserve(2);
in front of the insertions; this causes neither copy nor move to be executed.