I read the following article about rvalue references http://thbecker.net/articles/rvalue_references/section_01.html
But there are some things I did not understand.
This is the code i used:
#include <iostream>
template <typename T>
class PointerHolder
{
public:
// 1
explicit PointerHolder(T* t) : ptr(t)
{
std::cout << "default constructor" << std::endl;
}
// 2
PointerHolder(const PointerHolder& lhs) : ptr(new T(*(lhs.ptr)))
{
std::cout << "copy constructor (lvalue reference)" << std::endl;
}
// 3
PointerHolder(PointerHolder&& rhs) : ptr(rhs.ptr)
{
rhs.ptr = nullptr;
std::cout << "copy constructor (rvalue reference)" << std::endl;
}
// 4
PointerHolder& operator=(const PointerHolder& lhs)
{
std::cout << "copy operator (lvalue reference)" << std::endl;
delete ptr;
ptr = new T(*(lhs.ptr));
return *this;
}
// 5
PointerHolder& operator=(PointerHolder&& rhs)
{
std::cout << "copy operator (rvalue reference)" << std::endl;
std::swap(ptr, rhs.ptr);
return *this;
}
~PointerHolder()
{
delete ptr;
}
private:
T* ptr;
};
PointerHolder<int> getIntPtrHolder(int i)
{
auto returnValue = PointerHolder<int>(new int(i));
return returnValue;
}
If I comment constructors 2 and 3, the compiler says :
error: use of deleted function ‘constexpr PointerHolder<int>::PointerHolder(const PointerHolder<int>&)’
auto returnValue = PointerHolder<int>(new int(i));
^
../src/rvalue-references/move.cpp:4:7: note: ‘constexpr PointerHolder<int>::PointerHolder(const PointerHolder<int>&)’ is implicitly declared as deleted because ‘PointerHolder<int>’ declares a move constructor or move assignment operator
But If I uncomment any one of the two, it compiles and the execution yields the following :
default constructor
So these are my questions :
- When the constructors 2 and 3 where commented, it tried to call the constructor 2. Why ? I would expect it to call the constructor 1, which is what it did when i uncommented them !
- Regarding the error : I declared a "move" copy operator, which means that my object can be "move" copied from a rvalue reference. But why does it implicitly delete my normal copy constructor ? And if so why does it allow me to "undelete" it by defining it explicitly and use it ?