Reputation: 264471
I am trying to understand why unique_ptr
has a nullptr_t constructor
constexpr unique_ptr::unique_ptr( nullptr_t );
I had assumed this was because the normal one argument constructor was explicit and thus would reject the nullptr value:
explicit unique_ptr::unique_ptr( pointer p );
But when I build an example it compiler fine:
namespace ThorsAnvil
{
template<typename T>
class SmartPointer
{
public:
SmartPointer() {}
explicit SmartPointer(T*){}
};
}
template<typename T>
using SP = ThorsAnvil::SmartPointer<T>;
int main()
{
SP<int> data1;
SP<int> data2(new int); // fine
SP<int> data3(nullptr); // fine
}
Here is the output:
> g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix
> g++ -Wall -Wextra -std=c++11 SP1.cpp
Why does std::unique_ptr need the extra constructor that takes a nullptr_t argument?
Upvotes: 3
Views: 488
Reputation: 109159
SP<int> data3(nullptr); // fine
You're using direct initialization which causes the explicit
constructor to be considered. Try the following and your code won't compile
SP<int> data4 = nullptr;
Now add the following constructor and the line above will compile
SmartPointer(std::nullptr_t){}
So the nullptr_t
constructor makes a unique_ptr
behave like a raw pointer in the case where you want to initialize it to nullptr
, but avoids any surprising transfer of ownership in other cases where you might be actually assigning it a raw pointer.
Upvotes: 6