I am learning the behavior of std::vector
: how it relocates (copies/moves) objects when reserving more capacity:
#include<vector>
#include<iostream>
using namespace std;
struct A{
A(const A& a){ i=a.i; cerr<<"copied "<<i<<endl; } //(1)
A( A&& a){ i=a.i; cerr<<"moved "<<i<<endl; }
A(int i):i(i){cerr<<"created "<<i<<endl;};
A(){};
private:
int i=0;
};
int main()
{
vector<A> v1;
size_t prevcap=v1.capacity();
for(int i=0; i<10; ++i){
v1.emplace_back(i);
if(prevcap!=v1.capacity()){
cerr<<"capacity increased to "<<v1.capacity()<<endl;
prevcap=v1.capacity();
}
cerr<<"------"<<endl;
}
}
With my g++-10 the output is:
created 0
capacity increased to 1
------
created 1
copied 0
capacity increased to 2
------
created 2
copied 0
copied 1
capacity increased to 4
------
created 3
------
created 4
copied 0
copied 1
copied 2
copied 3
capacity increased to 8
------
created 5
------
created 6
------
created 7
------
created 8
copied 0
copied 1
copied 2
copied 3
copied 4
copied 5
copied 6
copied 7
capacity increased to 16
------
created 9
------
If remove copy-construtor (1)
the output would be:
created 0
capacity increased to 1
------
created 1
moved 0
capacity increased to 2
------
created 2
moved 0
moved 1
capacity increased to 4
------
created 3
------
created 4
moved 0
moved 1
moved 2
moved 3
capacity increased to 8
------
created 5
------
created 6
------
created 7
------
created 8
moved 0
moved 1
moved 2
moved 3
moved 4
moved 5
moved 6
moved 7
capacity increased to 16
------
created 9
------
Why if both copy and move ctors exist is the copy-ctor preferred?
Update. Thx to @Jarod42. Add noexcept
struct A{
A(const A& a)noexcept{ i=a.i; cerr<<"copied "<<i<<endl; }
A( A&& a)noexcept{ i=a.i; cerr<<"moved "<<i<<endl; }
A(int i)noexcept:i(i){cerr<<"created "<<i<<endl;};
A()noexcept{};
private:
int i=0;
};
output:
created 0
capacity increased to 1
------
created 1
moved 0
capacity increased to 2
------
created 2
moved 0
moved 1
capacity increased to 4
------
created 3
------
created 4
moved 0
moved 1
moved 2
moved 3
capacity increased to 8
------
created 5
------
created 6
------
created 7
------
created 8
moved 0
moved 1
moved 2
moved 3
moved 4
moved 5
moved 6
moved 7
capacity increased to 16
------
created 9
------
Now moved. But what is the logic behind this?