きっかけ
ポインタの管理を楽にするため、「std::unique_ptr」を使用することもあるかと思いますが、つい先日、こんなコードを見かけました。
std::unique_ptr<Hoge> pHoge = NULL;
あれ?NULLって0ですよね??
unique_ptrに0を代入するってどういうこと???
そもそも代入しようとしてもエラーになるのでは????
てことで、確認してみました。
unique_ptrでの処理
unique_ptrにNULL(0)を代入すると、以下のオペレータが使用されます。
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になるようです。
※こちらを参照
なお、
std::unique_ptr<Hoge> pHoge;
で宣言した場合も、以下の処理が実行され、NULLを指定したときと同じ処理が行われます。
unique_ptr() _NOEXCEPT
: _Mybase(pointer())
{ // default construct
static_assert(!is_pointer<_Dx>::value,
"unique_ptr constructed with null deleter pointer");
}
ちなみに、
std::unique_ptr<Hoge> pHoge;
pHoge = NULL;
とあとからNULLを代入すると、以下の処理が呼ばれます。
_Myt& operator=(nullptr_t) _NOEXCEPT
{ // assign a null pointer
reset();
return (*this);
}
こちらもちゃんとnullptr_tの代入が用意されています。
(中の処理は違いますが)
おまけ
当然のことながら、
std::unique_ptr<Hoge> pHoge = 1;
のようにスカラー値で初期化しようとしても、
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>ビルドに失敗しました。
とエラーになります。
また、
std::unique_ptr<Hoge> pHoge;
pHoge = 1;
のようにNULL(0)以外のスカラー値を代入しようとしても、コンパイルエラーになります。
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>ビルドに失敗しました。
まぁ、当たり前といえば当たり前なのですが ^^;