[Effective modern C++]says,
- vector::push_back will allocate new memory block when capacity is not enough,and then "copy or move" elements to the new block
- Whether to choose copy or move depends on a class A's move ctor having "noexcept" or not. This guarantees exception safety when elements move their home to new block.
So I did an experiment
#include<iostream>
#include<vector>
using namespace std;
struct A{
A(){}
A(const A&){ cout << "copy ctor\n"; }
A(A&&){ cout << "move ctor\n"; }
};
int main()
{
vector<A> vi(2);
size_t c = 0;
cout<<"========\n";
for (size_t i = 0; i<4; ++i)
{
cout<<"push_back...........\n";
vi.push_back(A());
if (vi.capacity()>c)
{
c = vi.capacity();
cout << c << endl;
}
}
return 0;
}
GCC/clang to run it,push_back judges if capacity not enough,all elements will be copied to new location. If I change move ctor to be A(A&&)noexcept, then it calls move ctor. This is exactly same as the book says
But I tested with VC2013/2015: no matter I added "noexcept" or not, it calls "move ctor" and never "copy ctor". Is this a bug of VC, or VC has compiler options to guarantee exception safe, but is not open by default?
Thanks.