namespace std {
template <class T>
shared_ptr(weak_ptr<T>) -> shared_ptr<T>; // (1)
template <class T, class D>
shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>; // (2)
}
概要
std::shared_ptr
クラステンプレートの型推論補助。
- (1) :
std::weak_ptr
からstd::shared_ptr
への変換 - (2) :
std::unique_ptr
からstd::shared_ptr
への変換
備考
- 生ポインタから
std::shared_ptr
への変換は推論できない。コンストラクタがtemplate <class Y> explicit shared_ptr(Y* p);
のようにクラステンプレートパラメータT
を直接使用しておらず、推論補助も定義されないからである - (
std::unique_ptr
の推論補助ページがないためここに書くが、) 生ポインタからstd::unique_ptr
への変換も推論できない。これは、クラス内でusing pointer = T*;
のようにT*
の別名を付けたうえで、コンストラクタがexplicit unique_ptr(pointer);
のように、T*
を直接使用せず、別名を使用しているためである - これらは、生ポインタが配列か単一要素かを、一意に決められないためである。
std::shared_ptr
とstd::unique_ptr
には、単一要素版と配列版が定義されるが、推論補助では、引数からどちらを使用するかを決められない
int* p = new int[5]; std::shared_ptr sp {p}; // 単一版か配列版かを決められないため、エラーとなるべき
例
#include <memory>
#include <type_traits>
#include <utility>
int main()
{
// (1)
// weak_ptrからshared_ptrへの変換
std::shared_ptr<int> sp1_org {new int(3)}; // 注: 生ポインタからの変換は、推論できない
std::weak_ptr wp = sp1_org;
std::shared_ptr sp1 {wp};
static_assert(std::is_same_v<
decltype(sp1),
std::shared_ptr<int>
>);
// (2)
// unique_ptrからshared_ptrへの変換
std::unique_ptr<int> up {new int(3)}; // 注: 生ポインタからunique_ptr<T>は推論できない
std::shared_ptr sp2 {std::move(up)};
static_assert(std::is_same_v<
decltype(sp2),
std::shared_ptr<int>
>);
}
出力
バージョン
言語
- C++17
処理系
- Clang:
- GCC: 7.1.0 ✅
- Visual C++: ??