std::make_unique, std::make_unique_for_overwrite - cppreference.com

From cppreference.com

Defined in header

<memory>

template<classT,class...Args>unique_ptr<T>make_unique(Args&&...args); (1)(since C++14)
(until C++23)
(only for non-array types)template<classT,class...Args>constexprunique_ptr<T>make_unique(Args&&...args);(since C++23)
(only for non-array types)template<classT>unique_ptr<T>make_unique(std::size_tsize); (2)(since C++14)
(until C++23)
(only for array types with unknown bound)template<classT>constexprunique_ptr<T>make_unique(std::size_tsize);(since C++23)
(only for array types with unknown bound)template<classT,class...Args>/* unspecified */make_unique(Args&&...args)=delete; (3) (since C++14)
(only for array types with known bound)template<classT>unique_ptr<T>make_unique_for_overwrite(); (4)(since C++20)
(until C++23)
(only for non-array types)template<classT>constexprunique_ptr<T>make_unique_for_overwrite();(since C++23)
(only for non-array types)template<classT>unique_ptr<T>make_unique_for_overwrite(std::size_tsize); (5)(since C++20)
(until C++23)
(only for array types with unknown bound)template<classT>constexprunique_ptr<T>make_unique_for_overwrite(std::size_tsize);(since C++23)
(only for array types with unknown bound)template<classT,class...Args>/* unspecified */make_unique_for_overwrite(Args&&...args)=delete; (6) (since C++20)
(only for array types with known bound)Constructs an object of type T and wraps it in a

std::unique_ptr

.

1) Constructs a non-array type T. The arguments args are passed to the constructor of T. This overload participates in overload resolution only if T is not an array type. The function is equivalent to:

unique_ptr<T>(newT(std::forward<Args>(args)...))2) Constructs an array of the given dynamic size. The array elements are

value-initialized

. This overload participates in overload resolution only if T is an array of unknown bound. The function is equivalent to:

unique_ptr<T>(newstd::remove_extent_t<T>[size]())3,6) Construction of arrays of known bound is disallowed.

4) Same as (1), except that the object is

default-initialized

. This overload participates in overload resolution only if T is not an array type. The function is equivalent to:

unique_ptr<T>(newT)5) Same as (2), except that the array is default-initialized. This overload participates in overload resolution only if T is an array of unknown bound. The function is equivalent to:

unique_ptr<T>(newstd::remove_extent_t<T>[size])Parameters

args - list of arguments with which an instance of T will be constructed size - the length of the array to construct Return value

std::unique_ptr

of an instance of type T.

Exceptions

May throw

std::bad_alloc

or any exception thrown by the constructor of T. If an exception is thrown, this function has no effect.

Possible Implementation

make_unique (1-3)

// C++14 make_uniquenamespacedetail{template<class>constexprboolis_unbounded_array_v=false;template<classT>constexprboolis_unbounded_array_v<T[]>=true;template<class>constexprboolis_bounded_array_v=false;template<classT,std::size_tN>constexprboolis_bounded_array_v<T[N]>=true;}// namespace detailtemplate<classT,class...Args>std::enable_if_t<!std::is_array<T>::value,std::unique_ptr<T>>make_unique(Args&&...args){returnstd::unique_ptr<T>(newT(std::forward<Args>(args)...));}template<classT>std::enable_if_t<detail::is_unbounded_array_v<T>,std::unique_ptr<T>>make_unique(std::size_tn){returnstd::unique_ptr<T>(newstd::remove_extent_t<T>[n]());}template<classT,class...Args>std::enable_if_t<detail::is_bounded_array_v<T>>make_unique(Args&&...)=delete;

make_unique_for_overwrite (4-6)

// C++20 make_unique_for_overwritetemplate<classT>requires(!std::is_array_v<T>)std::unique_ptr<T>make_unique_for_overwrite(){returnstd::unique_ptr<T>(newT);}template<classT>requiresstd::is_unbounded_array_v<T>std::unique_ptr<T>make_unique_for_overwrite(std::size_tn){returnstd::unique_ptr<T>(newstd::remove_extent_t<T>[n]);}template<classT,class...Args>requiresstd::is_bounded_array_v<T>voidmake_unique_for_overwrite(Args&&...)=delete;Notes

Unlike

std::make_shared

(which has

std::allocate_shared

), std::make_unique does not have an allocator-aware counterpart. allocate_unique proposed in

P0211

would be required to invent the deleter type D for the std::unique_ptr<T,D> it returns which would contain an allocator object and invoke both destroy and deallocate in its operator().

Feature-test

macro ValueStdFeature

__cpp_lib_make_unique

201304L

(C++14)std::make_unique; overload (

1

)

__cpp_lib_smart_ptr_for_overwrite

202002L

(C++20)Smart pointer creation with default initialization (

std::allocate_shared_for_overwrite

,

std::make_shared_for_overwrite

, std::make_unique_for_overwrite); overloads (

4-6

)

__cpp_lib_constexpr_memory

202202L

(C++23)constexpr for overloads (

1,2,4,5

)Example

Run this code

#include<cstddef>#include<iomanip>#include<iostream>#include<memory>#include<utility>structVec3{intx,y,z;// Following constructor is no longer needed since C++20.Vec3(intx=0,inty=0,intz=0)noexcept:x(x),y(y),z(z){}friendstd::ostream&operator<<(std::ostream&os,constVec3&v){returnos<<"{ x="<<v.x<<", y="<<v.y<<", z="<<v.z<<" }";}};// Output Fibonacci numbers to an output iterator.template<typenameOutputIt>OutputItfibonacci(OutputItfirst,OutputItlast){for(inta=0,b=1;first!=last;++first){*first=b;b+=std::exchange(a,b);}returnfirst;}intmain(){// 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);// Create a unique_ptr to an uninitialized array of 10 integers,// then populate it with Fibonacci numbers.std::unique_ptr<int[]>i1=std::make_unique_for_overwrite<int[]>(10);fibonacci(i1.get(),i1.get()+10);std::cout<<"make_unique<Vec3>(): "<<*v1<<'\n'<<"make_unique<Vec3>(0,1,2): "<<*v2<<'\n'<<"make_unique<Vec3[]>(5): ";for(std::size_ti=0;i<5;++i)std::cout<<std::setw(i?30:0)<<v3[i]<<'\n';std::cout<<'\n';std::cout<<"make_unique_for_overwrite<int[]>(10), fibonacci(...): ["<<i1[0];for(std::size_ti=1;i<10;++i)std::cout<<", "<<i1[i];std::cout<<"]\n";}Output:

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 } make_unique_for_overwrite<int[]>(10), fibonacci(...): [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] See also