2015-01-27 60 views
3

我試圖理解爲什麼unique_ptr有nullptr_t構造看的std ::的unique_ptr及其nullptr_t構造

constexpr unique_ptr::unique_ptr(nullptr_t); 

我曾以爲這是因爲正常的一個參數的構造函數是明確的,因此會拒絕nullptr值:

explicit unique_ptr::unique_ptr(pointer p); 

但是,當我建立一個例子是細編譯器:

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 
} 

這裏是輸出:

> 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 

爲什麼的std ::的unique_ptr需要額外的構造函數,一個nullptr_t說法?

+0

我的猜測,因爲它被宣佈爲'constexpr',因此被用於優化。 – Falmarri 2015-01-27 01:37:29

+0

'nullptr_t'構造函數是否也是'explicit'? – templatetypedef 2015-01-27 01:38:11

+0

@templatetypedef:不是。只是contexpr。 – 2015-01-27 01:38:46

回答

6
SP<int>  data3(nullptr); // fine 

您正在使用直接初始化,導致explicit構造函數被考慮。請嘗試以下,你的代碼將無法編譯

SP<int>  data4 = nullptr; 

現在添加下面的構造及以上線路將編譯

SmartPointer(std::nullptr_t){} 

所以nullptr_t構造使得unique_ptr的行爲很像的情況下的原始指針在那裏你想初始化它到nullptr,但是在其他情況下你可能實際上將它分配給一個原始指針的時候避免了所有權的任何令人驚訝的轉移。

+0

'SP data5 = new int;'也失敗。 – 2015-01-27 01:40:04

+0

@CrappyExperienceBye如果失敗,請參閱我剛剛添加的關於「令人驚訝」的所有權轉讓的最後一段。 – Praetorian 2015-01-27 01:42:13

+0

所以基本上這是爲了允許'SP newData = nullptr;'並且有一個等價的賦值版本來允許'newData = nullptr;'。因此,我們可以輕鬆地重置unqiue_ptr,但不會意外分配它。 – 2015-01-27 01:54:37

相關問題