Reputation: 157
I have the following code:
#include <bits/stdc++.h>
using namespace std;
class A {
public:
A(const A& a) noexcept { cout << "copy constructor" << endl; }
A& operator=(const A& a) noexcept { cout << "copy assignment operator" << endl; }
A(A&& a) noexcept { cout << "move constructor" << endl; }
A& operator=(A&& a) noexcept { cout << "move assignment operator" << endl; }
A() { cout << "default constructor" << endl; }
};
vector<A> aList;
void AddData(const A&& a)
{
aList.push_back(std::move(a));
}
int main()
{
AddData(A());
return 0;
}
The output is default constructor copy constructor
. please tell me is the rvalue reference push_back(T&&)
called? And when is copy constructor called?
Upvotes: 2
Views: 319
Reputation: 24738
The issue is with the a
parameter in AddData()
:
void AddData(const A&& a) // <-- const reference!!!
{
aList.push_back(std::move(a)); // selects push_back(const A&)
}
The a
parameter above is a const
rvalue reference. You are marking with std::move()
a const
object.
Marking a const
object with std::move()
for moving has no effect when it comes to move semantics because you can't move from a const
object (i.e., you need to alter the moved-from object, but it is const
-qualified).
An rvalue reference doesn't bind to a const
object, but a const
lvalue reference does. As a result, the push_back(const A&)
overload is selected instead of the push_back(A&&)
one, and therefore the A
object is copy constructed.
Use a non-const
rvalue reference instead:
void AddData(A&& a) // <-- non-const reference
{
aList.push_back(std::move(a)); // selects push_back(A&&)
}
Upvotes: 8