Using GCC 4.7.0, vector seems to prefer copy rather than move when resizing. The following program produces different (and I think incorrect) results under GCC 4.7.0 vs GCC 4.6.1 #include <iostream> #include <vector> struct Stuff { Stuff( ) { } Stuff( Stuff&& o ) { std::cout << "Move" << std::endl; } Stuff( const Stuff& o ) { std::cout << "Copy" << std::endl; } }; int main( const int argc, const char** argv ) { std::vector< Stuff > stuff; std::cout << "1" << std::endl; stuff.push_back( Stuff() ); std::cout << "2" << std::endl; stuff.push_back( Stuff() ); std::cout << "3" << std::endl; stuff.push_back( Stuff() ); } Here is the output under GCC 4.6.1 jonathan@grindserv:~$ g++-4.6.1 -std=c++0x test.cpp jonathan@grindserv:~$ ./a.out 1 Move 2 Move Move 3 Move Move Move Here is the output under GCC 4.7.0 jonathan@grindserv:~$ g++-4.7.0 -std=c++0x test.cpp jonathan@grindserv:~$ ./a.out 1 Move 2 Move Copy 3 Move Copy Copy
But Stuff' move-constructor isn't known not to throw...
(In reply to comment #1) > But Stuff' move-constructor isn't known not to throw... Okay, so it is a new requirement for move constructors to be marked as nothrow in order for vector to use them for relocation?
Otherwise, if the move constructor by chance throws, the push_back cannot have no effects, as required by 23.2.1/10. Actually the requirement holds for all the containers, but only std::vector implements it in 4.7, the other containers (I *think* only std::deque needs work) will follow.
(In reply to comment #3) > Otherwise, if the move constructor by chance throws, the push_back cannot have > no effects, as required by 23.2.1/10. Actually the requirement holds for all > the containers, but only std::vector implements it in 4.7, the other containers > (I *think* only std::deque needs work) will follow. In my example code, if you comment out the copy constructor (leaving only the move constructor) then vector will use the (potentially throwing) move constructor. If what you say is the case, shouldn't vector refuse to use the move constructor?
That's known, it's a design choice: in that case you are essentially back to the unsafe 4.6 behavior. Look for 'move_if_noexcept'.
Essentially the leeway for the unsafe fallback in the case of Comment #4 is provided by 23.3.6.5/1: "If an exception is thrown by the move constructor of a non-CopyInsertable T, the effects are unspecified". But really, historically, people simply decided to replace for reallocations unconditional moves with move_if_noexcexpt.
Thanks Paolo. I understand the situation now. Thanks for your time and sorry the erroneous report!