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++: ??