Reputation: 7804
This problem seems strange but I've checked with multiple compilers. In my code, I have a Move Constructor
and a copy constructor
as
class A {
int val;
public:
A(int var) : val(var) {
}
A( A && a1) {
cout<<"M Value -> "<<a1.val<<endl;
cout<<"Move Cons..."<<endl;
}
A(const A & a1) {
cout<<"Copy Cons.."<<endl;
cout<<"Value -> "<<a1.val<<endl;
}
};
If I write my main
function as
int main()
{
vector<A> v1;
A a2(200);
v1.push_back(move(a2));
}
The output is
M Value -> 200
Move Cons...
Which is expected, but if I changed my main
function as
int main()
{
vector<A> v1;
A a2(200);
v1.push_back(A(100));
v1.push_back(move(a2));
}
I get the following output
M Value -> 100
Move Cons...
M Value -> 200
Move Cons...
Copy Cons.. // unexpected
Value -> 0 // unexpected
Can anyone help me in understanding where and how this copy constructor
gets called.. that too with value 0
Thanks
Upvotes: 4
Views: 172
Reputation: 579
The reasons were already answered in the comments. I will try to illustrate what's going on.
vector<A> v1;
v1.push_back(A(100));
A(100)
inside the vector.v1.push_back(move(a2));
std::vector
keeps its content in contiguous memory.a2
inside the v1
.v1
to the new v1
.1) ## v1[undef ] #########################
2) ## v1[A(100)] #########################
3) ## [A(100)] ### v1[undef, undef ] ##
4) ## [A(100)] ### v1[undef, A(200)] ##
5) ## [A(100)] ### v1[A(100), A(200)] ##
Related to the value 0, that's because these copy and move constructors actually do nothing and val
value remain undefined.
With proper constructors, this log should be 100.
If you mark the move constructor as noexcept
, it will be used in the reallocation process instead of the copy one.
You can use v1.emplace_back(100)
instead of v1.push_back(A(100))
avoiding move.
Upvotes: 1