std::unique_ptrの初期化

# きっかけ

ポインタの管理を楽にするため、「std::unique_ptr」を使用することもあるかと思いますが、つい先日、こんなコードを見かけました。

```C++
std::unique_ptr<Hoge> pHoge = NULL;
```

あれ？NULLって0ですよね？？
unique_ptrに0を代入するってどういうこと？？？
そもそも代入しようとしてもエラーになるのでは？？？？

てことで、確認してみました。

# unique_ptrでの処理

unique_ptrにNULL（0）を代入すると、以下のオペレータが使用されます。

```C++
unique_ptr(nullptr_t) _NOEXCEPT
    : _Mybase(pointer())
    {    // null pointer construct
    static_assert(!is_pointer<_Dx>::value,
        "unique_ptr constructed with null deleter pointer");
    }
```

ちゃんとコンストラクタが用意されており、NULL（0）を「nullptr_t」と解釈してくれたようです。
今回、テンプレートとしてクラスを指定していますので、nullptr_tは0になるようです。
※[こちら](https://cpprefjp.github.io/reference/cstddef/nullptr_t.html)を参照

なお、

```C++
std::unique_ptr<Hoge> pHoge;
```

で宣言した場合も、以下の処理が実行され、NULLを指定したときと同じ処理が行われます。

```C++
unique_ptr() _NOEXCEPT
    : _Mybase(pointer())
    {    // default construct
    static_assert(!is_pointer<_Dx>::value,
        "unique_ptr constructed with null deleter pointer");
    }
```


ちなみに、

```C++
std::unique_ptr<Hoge> pHoge;
pHoge = NULL;
```

とあとからNULLを代入すると、以下の処理が呼ばれます。

```C++
_Myt& operator=(nullptr_t) _NOEXCEPT
    {    // assign a null pointer
    reset();
    return (*this);
    }
```

こちらもちゃんとnullptr_tの代入が用意されています。
（中の処理は違いますが）

# おまけ

当然のことながら、

```C++
std::unique_ptr<Hoge> pHoge = 1;
```

のようにスカラー値で初期化しようとしても、

```C++
1>c:\tmp\unique_ptr\unique_ptr\unique_ptr.cpp(16): error C2440: '初期化中' : 'int' から 'std::unique_ptr<_Ty>' に変換できません。
1>          with
1>          [
1>              _Ty=Hoge
1>          ]
1>          コンストラクターはソース型を持てません、またはコンストラクターのオーバーロードの解決があいまいです。
1>c:\tmp\unique_ptr\unique_ptr\unique_ptr.cpp(24): error C2679: 二項演算子 '=' : 型 'int' の右オペランドを扱う演算子が見つかりません (または変換できません)。
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1309): 'std::unique_ptr<_Ty> &std::unique_ptr<_Ty>::operator =(std::nullptr_t) throw()' の可能性があります。
1>          with
1>          [
1>              _Ty=Hoge
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1380): または 'std::unique_ptr<_Ty> &std::unique_ptr<_Ty>::operator =(std::unique_ptr<_Ty> &&) throw()'
1>          with
1>          [
1>              _Ty=Hoge
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1448): または 'std::unique_ptr<_Ty> &std::unique_ptr<_Ty>::operator =(const std::unique_ptr<_Ty> &)'
1>          with
1>          [
1>              _Ty=Hoge
1>          ]
1>          引数リスト '(std::unique_ptr<_Ty>, int)' を一致させようとしているとき
1>          with
1>          [
1>              _Ty=Hoge
1>          ]
1>
1>ビルドに失敗しました。
```

とエラーになります。
また、

```C++
std::unique_ptr<Hoge> pHoge;
pHoge = 1;
```

のようにNULL（0）以外のスカラー値を代入しようとしても、コンパイルエラーになります。

```text
1>c:\tmp\unique_ptr\unique_ptr\unique_ptr.cpp(22): error C2679: 二項演算子 '=' : 型 'int' の右オペランドを扱う演算子が見つかりません (または変換できません)。
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1309): 'std::unique_ptr<_Ty> &std::unique_ptr<_Ty>::operator =(std::nullptr_t) throw()' の可能性があります。
1>          with
1>          [
1>              _Ty=Hoge
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1380): または 'std::unique_ptr<_Ty> &std::unique_ptr<_Ty>::operator =(std::unique_ptr<_Ty> &&) throw()'
1>          with
1>          [
1>              _Ty=Hoge
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1448): または 'std::unique_ptr<_Ty> &std::unique_ptr<_Ty>::operator =(const std::unique_ptr<_Ty> &)'
1>          with
1>          [
1>              _Ty=Hoge
1>          ]
1>          引数リスト '(std::unique_ptr<_Ty>, int)' を一致させようとしているとき
1>          with
1>          [
1>              _Ty=Hoge
1>          ]
1>
1>ビルドに失敗しました。
```

まぁ、当たり前といえば当たり前なのですが ^^;