std::make_unique, std::make_unique_for_overwrite
提供: cppreference.com
<tbody>
</tbody>
| ヘッダ <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 typename std::remove_extent<T>::type[size]())
3,6) サイズの既知な配列の構築は禁止されています。
4) (1) と同じですが、オブジェクトはデフォルト初期化されます。 このオーバーロードは、
T が配列型でない場合にのみ、オーバーロード解決に参加します。 この関数は以下と同等です。
unique_ptr<T>(new T)
5) (2) と同じですが、配列はデフォルト初期化されます。 このオーバーロードは、
T がサイズの未知な配列である場合にのみ、オーバーロード解決に参加します。 この関数は以下と同等です。
unique_ptr<T>(new typename std::remove_extent<T>::type[size])
引数
| args | - | T のインスタンスを構築するための引数リスト
|
| size | - | 構築する配列のサイズ |
戻り値
T 型のインスタンスの std::unique_ptr。
例外
std::bad_alloc または T のコンストラクタによって投げられるあらゆる例外が投げられる可能性があります。 例外が投げられた場合、この関数は効果を持ちません。
実装例
| 1つめのバージョン |
|---|
// C++14 make_unique
namespace detail {
template<class>
static constexpr bool is_unbounded_array_v = false;
template<class T>
static constexpr bool is_unbounded_array_v<T[]> = true;
template<class>
static constexpr bool is_bounded_array_v = false;
template<class T, std::size_t N>
static constexpr bool 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)
{
return std::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)
{
return std::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_overwrite
template<class T>
requires !std::is_array_v<T>
std::unique_ptr<T> make_unique_for_overwrite()
{
return std::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)
{
return std::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) { }
friend std::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 arguments
std::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2);
// Create a unique_ptr to an array of 5 elements
std::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 を作成します (関数テンプレート) |