Why does reallocating a vector copy instead of moving the elements?

c++, c++11, move-semantics, stdvector

Solution

Tip-of-trunk clang + libc++ gets:

foo(1)
foo(2)
foo(move(foo(1))
~foo(2)
~foo(1)

If you remove the `noexcept` from the move constructor, then you get the copy solution:

foo(1)
foo(2)
foo(foo(1))
~foo(1)
~foo(2)
~foo(1)

Problem

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.

Original source

Related problems