|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
unique_ptr::unique_ptr | ||||
| Modifiers | ||||
| Observers | ||||
| Non-member functions | ||||
(C++14)(C++20) | ||||
(until C++20)(C++20) | ||||
(C++20) | ||||
| Helper classes | ||||
members of the primary template, unique_ptr<T> | ||
constexpr unique_ptr()noexcept; constexpr unique_ptr(std::nullptr_t)noexcept; | (1) | |
explicit unique_ptr( pointer p)noexcept; | (2) | (constexpr since C++23) |
unique_ptr( pointer p,/* see below */ d1)noexcept; | (3) | (constexpr since C++23) |
unique_ptr( pointer p,/* see below */ d2)noexcept; | (4) | (constexpr since C++23) |
unique_ptr( unique_ptr&& u)noexcept; | (5) | (constexpr since C++23) |
template<class U,class E> unique_ptr( unique_ptr<U, E>&& u)noexcept; | (6) | (constexpr since C++23) |
unique_ptr(const unique_ptr&)= delete; | (7) | |
template<class U> unique_ptr(std::auto_ptr<U>&& u)noexcept; | (8) | (removed in C++17) |
members of the specialization for arrays, unique_ptr<T[]> | ||
constexpr unique_ptr()noexcept; constexpr unique_ptr(std::nullptr_t)noexcept; | (1) | |
template<class U> explicit unique_ptr( U p)noexcept; | (2) | (constexpr since C++23) |
template<class U> unique_ptr( U p,/* see below */ d1)noexcept; | (3) | (constexpr since C++23) |
template<class U> unique_ptr( U p,/* see below */ d2)noexcept; | (4) | (constexpr since C++23) |
unique_ptr( unique_ptr&& u)noexcept; | (5) | (constexpr since C++23) |
template<class U,class E> unique_ptr( unique_ptr<U, E>&& u)noexcept; | (6) | (constexpr since C++23) |
unique_ptr(const unique_ptr&)= delete; | (7) | |
std::unique_ptr that owns nothing. Value-initializes the stored pointer and the stored deleter. Requires thatDeleter isDefaultConstructible and that construction does not throw an exception. These overloads participate in overload resolution only ifstd::is_default_constructible<Deleter>::value istrue andDeleter is not a pointer type.std::unique_ptr which ownsp, initializing the stored pointer withp and value-initializing the stored deleter. Requires thatDeleter isDefaultConstructible and that construction does not throw an exception. This overload participates in overload resolution only ifstd::is_default_constructible<Deleter>::value istrue andDeleter is not a pointer type.This constructor is not selected byclass template argument deduction. | (since C++17) |
std::unique_ptr object which ownsp, initializing the stored pointer withp and initializing a deleterD as below (depends upon whetherD is a reference type).D is non-reference typeA, then the signatures are:unique_ptr(pointer p,const A& d)noexcept; | (1) | (requires thatDeleter is nothrow-CopyConstructible) |
unique_ptr(pointer p, A&& d)noexcept; | (2) | (requires thatDeleter is nothrow-MoveConstructible) |
D is an lvalue-reference typeA&, then the signatures are:unique_ptr(pointer p, A& d)noexcept; | (1) | |
unique_ptr(pointer p, A&& d)= delete; | (2) | |
D is an lvalue-reference typeconst A&, then the signatures are:unique_ptr(pointer p,const A& d)noexcept; | (1) | |
unique_ptr(pointer p,const A&& d)= delete; | (2) | |
These two constructors are not selected byclass template argument deduction. | (since C++17) |
U is the same type aspointer, orU isstd::nullptr_t, orpointer is the same type aselement_type* andU is some pointer typeV* such thatV(*)[] is implicitly convertible toelement_type(*)[].unique_ptr by transferring ownership fromu to*this and stores the null pointer inu. This constructor only participates in overload resolution ifstd::is_move_constructible<Deleter>::value istrue. IfDeleter is not a reference type, requires that it is nothrow-MoveConstructible (ifDeleter is a reference,get_deleter() andu.get_deleter() after move construction reference the same value).unique_ptr by transferring ownership fromu to*this, whereu is constructed with a specified deleter (E). It depends upon whetherE is a reference type, as following:E is a reference type, this deleter is copy constructed fromu's deleter (requires that this construction does not throw),E is a non-reference type, this deleter is move constructed fromu's deleter (requires that this construction does not throw).pointer,Deleter is a reference type andE is the same type asDeleter, orDeleter is not a reference type andE is implicitly convertible toDeleter.U is an array type,pointer is the same type aselement_type*,element_type(*)[],Deleter is a reference type andE is the same type asDeleter, orDeleter is not a reference type andE is implicitly convertible toDeleter.unique_ptr where the stored pointer is initialized withu.release() and the stored deleter is value-initialized. This constructor only participates in overload resolution ifU* is implicitly convertible toT* andDeleter is the same type asstd::default_delete<T>.Contents |
| p | - | a pointer to an object to manage |
| d1, d2 | - | a deleter to use to destroy the object |
| u | - | another smart pointer to acquire the ownership from |
Instead of using the overload(2) together with new, it is often a better idea to usestd::make_unique<T>. | (since C++14) |
std::unique_ptr<Derived> is implicitly convertible tostd::unique_ptr<Base> through the overload(6) (because both the managed pointer andstd::default_delete are implicitly convertible).
Because the default constructor isconstexpr, static unique_ptrs are initialized as part ofstatic non-local initialization, before any dynamic non-local initialization begins. This makes it safe to use a unique_ptr in a constructor of any static object.
There is noclass template argument deduction from pointer type because it is impossible to distinguish a pointer obtained from array and non-array forms ofnew. | (since C++17) |
#include <iostream>#include <memory> struct Foo// object to manage{ Foo(){std::cout<<"Foo ctor\n";} Foo(const Foo&){std::cout<<"Foo copy ctor\n";} Foo(Foo&&){std::cout<<"Foo move ctor\n";} ~Foo(){std::cout<<"~Foo dtor\n";}}; struct D// deleter{ D(){}; D(const D&){std::cout<<"D copy ctor\n";} D(D&){std::cout<<"D non-const copy ctor\n";} D(D&&){std::cout<<"D move ctor\n";}void operator()(Foo* p)const{std::cout<<"D is deleting a Foo\n"; delete p;};}; int main(){std::cout<<"Example constructor(1)...\n";std::unique_ptr<Foo> up1;// up1 is emptystd::unique_ptr<Foo> up1b(nullptr);// up1b is empty std::cout<<"Example constructor(2)...\n";{std::unique_ptr<Foo> up2(new Foo);//up2 now owns a Foo}// Foo deleted std::cout<<"Example constructor(3)...\n"; D d;{// deleter type is not a referencestd::unique_ptr<Foo, D> up3(new Foo, d);// deleter copied}{// deleter type is a referencestd::unique_ptr<Foo, D&> up3b(new Foo, d);// up3b holds a reference to d} std::cout<<"Example constructor(4)...\n";{// deleter is not a referencestd::unique_ptr<Foo, D> up4(new Foo, D());// deleter moved} std::cout<<"Example constructor(5)...\n";{std::unique_ptr<Foo> up5a(new Foo);std::unique_ptr<Foo> up5b(std::move(up5a));// ownership transfer} std::cout<<"Example constructor(6)...\n";{std::unique_ptr<Foo, D> up6a(new Foo, d);// D is copiedstd::unique_ptr<Foo, D> up6b(std::move(up6a));// D is moved std::unique_ptr<Foo, D&> up6c(new Foo, d);// D is a referencestd::unique_ptr<Foo, D> up6d(std::move(up6c));// D is copied} #if (__cplusplus < 201703L)std::cout<<"Example constructor(7)...\n";{std::auto_ptr<Foo> up7a(new Foo);std::unique_ptr<Foo> up7b(std::move(up7a));// ownership transfer}#endif std::cout<<"Example array constructor...\n";{std::unique_ptr<Foo[]> up(new Foo[3]);}// three Foo objects deleted}
Output:
Example constructor(1)...Example constructor(2)...Foo ctor~Foo dtorExample constructor(3)...Foo ctorD copy ctorD is deleting a Foo~Foo dtorFoo ctorD is deleting a Foo~Foo dtorExample constructor(4)...Foo ctorD move ctorD is deleting a Foo~Foo dtorExample constructor(5)...Foo ctor~Foo dtorExample constructor(6)...Foo ctorD copy ctorD move ctorFoo ctorD non-const copy ctorD is deleting a Foo~Foo dtorD is deleting a Foo~Foo dtorExample constructor(7)...Foo ctor~Foo dtorExample array constructor...Foo ctorFoo ctorFoo ctor~Foo dtor~Foo dtor~Foo dtor
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 2118 | C++11 | Constructors ofunique_ptr<T[]> rejected qualification conversions. | Accept. |
| LWG 2520 | C++11 | unique_ptr<T[]> was accidentally made non-constructible fromnullptr_t. | Made constructible. |
| LWG 2801 | C++11 | The default constructor was not constrained. | Constrained. |
| LWG 2899 | C++11 | The move constructor was not constrained. | Constrained. |
| LWG 2905 | C++11 | Constraint on the constructor from a pointer and a deleter was wrong. | Corrected. |
| LWG 2944 | C++11 | Some preconditions were accidentally dropped by LWG 2905 | Restored. |