简体   繁体   中英

Looking at std::unique_ptr and its nullptr_t constructor

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM