std::make_unique, std::make_unique_for_overwrite
提供: cppreference.com
< cpp | memory | unique ptr
ヘッダ <memory> で定義 | ||
template<class T, class... Args> unique_ptr<T> make_unique( Args&&... args); | (1) | (C++14以上) (非配列型に対してのみ) |
template<class T > unique_ptr<T> make_unique(std::size_t size ); | (2) | (C++14以上) (サイズの未知な配列型に対してのみ) |
template<class T, class... Args> /* unspecified */ make_unique( Args&&... args)= delete; | (3) | (C++14以上) (サイズの既知な配列型に対してのみ) |
template<class T > unique_ptr<T> make_unique_for_overwrite(); | (4) | (C++20以上) (非配列型に対してのみ) |
template<class T > unique_ptr<T> make_unique_for_overwrite(std::size_t size ); | (5) | (C++20以上) (サイズの未知な配列型に対してのみ) |
template<class T, class... Args> /* unspecified */ make_unique_for_overwrite( Args&&... args)= delete; | (6) | (C++20以上) (サイズの未知な配列型に対してのみ) |
T
型のオブジェクトを構築し、それを std::unique_ptr でラップします。
1) 非配列型
T
を構築します。 引数 args
は T
のコンストラクタに渡されます。 このオーバーロードは、T
が配列型でない場合にのみ、オーバーロード解決に参加します。 この関数は以下と同等です。 unique_ptr<T>(new T(std::forward<Args>(args)...))
2) サイズの不明な配列
T
を構築します。 このオーバーロードは、T
がサイズの不明な配列である場合にのみ、オーバーロード解決に参加します。 この関数は以下と同等です。 unique_ptr<T>(new typenamestd::remove_extent<T>::type[size]())
3,6) サイズの既知な配列の構築は禁止されています。
4)(1) と同じですが、オブジェクトはデフォルト初期化されます。 このオーバーロードは、
T
が配列型でない場合にのみ、オーバーロード解決に参加します。 この関数は以下と同等です。 unique_ptr<T>(new T)
5)(2) と同じですが、配列はデフォルト初期化されます。 このオーバーロードは、
T
がサイズの未知な配列である場合にのみ、オーバーロード解決に参加します。 この関数は以下と同等です。 unique_ptr<T>(new typenamestd::remove_extent<T>::type[size])
目次 |
[編集]引数
args | - | T のインスタンスを構築するための引数リスト |
size | - | 構築する配列のサイズ |
[編集]戻り値
T
型のインスタンスの std::unique_ptr。
[編集]例外
std::bad_alloc または T
のコンストラクタによって投げられるあらゆる例外が投げられる可能性があります。 例外が投げられた場合、この関数は効果を持ちません。
[編集]実装例
1つめのバージョン |
---|
// C++14 make_uniquenamespace detail {template<class>staticconstexprbool is_unbounded_array_v =false;template<class T>staticconstexprbool is_unbounded_array_v<T[]>=true; template<class>staticconstexprbool is_bounded_array_v =false;template<class T, std::size_t N>staticconstexprbool is_bounded_array_v<T[N]>=true;}// namespace detail template<class T, class... Args>std::enable_if_t<!std::is_array<T>::value, std::unique_ptr<T>> make_unique(Args&&... args){returnstd::unique_ptr<T>(new T(std::forward<Args>(args)...));} template<class T>std::enable_if_t<detail::is_unbounded_array_v<T>, std::unique_ptr<T>> make_unique(std::size_t n){returnstd::unique_ptr<T>(new std::remove_extent_t<T>[n]());} template<class T, class... Args>std::enable_if_t<detail::is_bounded_array_v<T>> make_unique(Args&&...)= delete; |
2つめのバージョン |
// C++20 make_unique_for_overwritetemplate<class T> requires !std::is_array_v<T>std::unique_ptr<T> make_unique_for_overwrite(){returnstd::unique_ptr<T>(new T);} template<class T, std::size_t N> requires std::is_unbounded_array_v<T>std::unique_ptr<T> make_unique_for_overwrite(std::size_t n){returnstd::unique_ptr<T>(new std::remove_extent_t<T>[n]);} template<class T, class... Args> requires std::is_bounded_array_v<T>void make_unique_for_overwrite(Args&&...)= delete; |
[編集]ノート
std::allocate_shared がある std::make_shared とは異なり、 std::make_unique
にはアロケータ対応版がありません。 仮に allocate_unique
を作るとすると、アロケータオブジェクトを持ち、 operator()
で destroy
と deallocate
の両方を呼ぶ、戻り値となる unique_ptr<T,D>
のためのデリータ型 D
を考案する必要があるでしょう。
[編集]例
Run this code
#include <iostream>#include <memory> struct Vec3 {int x, y, z; Vec3(): x(0), y(0), z(0){} Vec3(int x, int y, int z):x(x), y(y), z(z){}friendstd::ostream& operator<<(std::ostream& os, Vec3& v){return os <<'{'<<"x:"<< v.x<<" y:"<< v.y<<" z:"<< v.z<<'}';}}; int main(){// Use the default constructor.std::unique_ptr<Vec3> v1 = std::make_unique<Vec3>();// Use the constructor that matches these argumentsstd::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2);// Create a unique_ptr to an array of 5 elementsstd::unique_ptr<Vec3[]> v3 = std::make_unique<Vec3[]>(5); std::cout<<"make_unique<Vec3>(): "<<*v1 <<'\n'<<"make_unique<Vec3>(0,1,2): "<<*v2 <<'\n'<<"make_unique<Vec3[]>(5): "<<'\n';for(int i =0; i <5; i++){std::cout<<" "<< v3[i]<<'\n';}}
出力:
make_unique<Vec3>(): {x:0 y:0 z:0} make_unique<Vec3>(0,1,2): {x:0 y:1 z:2} make_unique<Vec3[]>(5): {x:0 y:0 z:0} {x:0 y:0 z:0} {x:0 y:0 z:0} {x:0 y:0 z:0} {x:0 y:0 z:0}
[編集]関連項目
新しい unique_ptr を構築します (パブリックメンバ関数) | |
新しいオブジェクトを管理する shared_ptr を作成します (関数テンプレート) |