2

[Effective modern C++]says,

  1. vector::push_back will allocate new memory block when capacity is not enough,and then "copy or move" elements to the new block
  2. 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.

Hind Forsum
  • 9,717
  • 13
  • 63
  • 119

0 Answers0