Reputation: 10415
So I have a simple example of a class which has two member variables. And I've declared a copy and a move constructor which are = default
, which would force the compiler to generate them for me. Now my question is this. When the move constructor (or assignment) is used, why does the object from which I've moved stay intact?
For example if I have:
myclass obj(4, 5);
myclass obj2 = std::move(4, 5);
As I understand it, after the second line obj
will contain "nothing", as it will have been moved into obj2
which will have the values (4, 5)
. I know I'm not using to correct terms here....
Full code:
#include <iostream>
#include <utility>
template<class T1, class T2>
class Pair
{
public:
T1 first;
T2 second;
public:
//CONSTRUCTORS
constexpr Pair() = default;
constexpr Pair(const T1& _first, const T2& _second)
: first(_first), second(_second)
{}
constexpr Pair(T1&& _first, T2&& _second)
: first(std::forward<T1>(_first)), second(std::forward<T2>(_second))
{}
constexpr Pair(const Pair&) = default;
constexpr Pair(Pair&&) = default;
//ASSIGNMENT
Pair &operator=(const Pair&) = default;
Pair &operator=(Pair&&) = default;
};
int main()
{
Pair<int, int> p(1, 2);
Pair<int, int> p2 = p; //all good, p = {1, 2} and p2 = {1, 2}
Pair<int, int> p3 = std::move(p); //p = {1, 2} and p3 = {1, 2}
//why isn't p "moved" into p3??
//p should be empty??
//same thing occurs with the move assignment. why?
std::cout << p.first << " " << p.second << "\n";
std::cout << p2.first << " " << p2.second << "\n";
std::cout << p3.first << " " << p3.second << "\n";
}
Live example: http://coliru.stacked-crooked.com/a/82d85da23eb44e66
Upvotes: 1
Views: 97
Reputation: 41750
The default move constructor and move assignement will simply call std::move
to all members. Just like the copy, the default copy constructor simple call the copy of all members.
Your code is correct, and after calling std::move
, it's normal the moved data still exist. Why? Because std::move
on primitive copies them. The compiler will not produce code to make moved int to 0
, so it's a simple copy. However, if you pair contains a more complex type such as a std::vector<int>
, the moved vector will effectively end up empty.
Upvotes: 2