20 Memory management library [mem]

20.3 Smart pointers [smartptr]

20.3.1 Unique-ownership pointers [unique.ptr]

20.3.1.3 unique_ptr for single objects [unique.ptr.single]

20.3.1.3.1 General [unique.ptr.single.general]

namespace std { template<class T, class D = default_delete<T>> class unique_ptr { public: using pointer = see below; using element_type = T; using deleter_type = D; // [unique.ptr.single.ctor], constructors constexpr unique_ptr() noexcept; constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept; constexpr unique_ptr(type_identity_t<pointer> p, see below d1) noexcept; constexpr unique_ptr(type_identity_t<pointer> p, see below d2) noexcept; constexpr unique_ptr(unique_ptr&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; template<class U, class E> constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept; // [unique.ptr.single.dtor], destructor constexpr ~unique_ptr(); // [unique.ptr.single.asgn], assignment constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; constexpr unique_ptr& operator=(nullptr_t) noexcept; // [unique.ptr.single.observers], observers constexpr add_lvalue_reference_t<T> operator*() const noexcept(see below); constexpr pointer operator->() const noexcept; constexpr pointer get() const noexcept; constexpr deleter_type& get_deleter() noexcept; constexpr const deleter_type& get_deleter() const noexcept; constexpr explicit operator bool() const noexcept; // [unique.ptr.single.modifiers], modifiers constexpr pointer release() noexcept; constexpr void reset(pointer p = pointer()) noexcept; constexpr void swap(unique_ptr& u) noexcept; // disable copy from lvalue unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; }; }
The default type for the template parameter D is default_delete.
A client-supplied template argument D shall be a function object type ([function.objects]), lvalue reference to function, or lvalue reference to function object type for which, given a value d of type D and a value ptr of type unique_ptr<T, D>​::​pointer, the expression d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.
If the deleter's type D is not a reference type, D shall meet the Cpp17Destructible requirements (Table 35).
If the qualified-id remove_reference_t<D>​::​pointer is valid and denotes a type ([temp.deduct]), then unique_ptr<T, D>​::​pointer shall be a synonym for remove_reference_t<D>​::​pointer.
Otherwise unique_ptr<T, D>​::​pointer shall be a synonym for element_type*.
The type unique_ptr<T, D>​::​pointer shall meet the Cpp17NullablePointer requirements (Table 36).
[Example 1: 
Given an allocator type X ([allocator.requirements.general]) and letting A be a synonym for allocator_traits<X>, the types A​::​pointer, A​::​const_pointer, A​::​void_pointer, and A​::​const_void_pointer may be used as unique_ptr<T, D>​::​pointer.
— end example]

20.3.1.3.2 Constructors [unique.ptr.single.ctor]

constexpr unique_ptr() noexcept; constexpr unique_ptr(nullptr_t) noexcept;
Constraints: is_pointer_v<deleter_type> is false and is_default_constructible_v<deleter_type> is true.
Preconditions: D meets the Cpp17DefaultConstructible requirements (Table 30), and that construction does not throw an exception.
Effects: Constructs a unique_ptr object that owns nothing, value-initializing the stored pointer and the stored deleter.
Postconditions: get() == nullptr.
get_deleter() returns a reference to the stored deleter.
constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept;
Constraints: is_pointer_v<deleter_type> is false and is_default_constructible_v<deleter_type> is true.
Preconditions: D meets the Cpp17DefaultConstructible requirements (Table 30), and that construction does not throw an exception.
Effects: Constructs a unique_ptr which owns p, initializing the stored pointer with p and value-initializing the stored deleter.
Postconditions: get() == p.
get_deleter() returns a reference to the stored deleter.
constexpr unique_ptr(type_identity_t<pointer> p, const D& d) noexcept; constexpr unique_ptr(type_identity_t<pointer> p, remove_reference_t<D>&& d) noexcept;
Constraints: is_constructible_v<D, decltype(d)> is true.
Preconditions: For the first constructor, if D is not a reference type, D meets the Cpp17CopyConstructible requirements and such construction does not exit via an exception.
For the second constructor, if D is not a reference type, D meets the Cpp17MoveConstructible requirements and such construction does not exit via an exception.
Effects: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and initializing the deleter from std​::​forward<decltype(d)>(d).
Postconditions: get() == p.
get_deleter() returns a reference to the stored deleter.
If D is a reference type then get_deleter() returns a reference to the lvalue d.
Remarks: If D is a reference type, the second constructor is defined as deleted.
[Example 1: D d; unique_ptr<int, D> p1(new int, D()); // D must be Cpp17MoveConstructible unique_ptr<int, D> p2(new int, d); // D must be Cpp17CopyConstructible unique_ptr<int, D&> p3(new int, d); // p3 holds a reference to d unique_ptr<int, const D&> p4(new int, D()); // error: rvalue deleter object combined // with reference deleter type — end example]
constexpr unique_ptr(unique_ptr&& u) noexcept;
Constraints: is_move_constructible_v<D> is true.
Preconditions: If D is not a reference type, D meets the Cpp17MoveConstructible requirements (Table 31).
Construction of the deleter from an rvalue of type D does not throw an exception.
Effects: Constructs a unique_ptr from u.
If D is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
[Note 1: 
The construction of the deleter can be implemented with std​::​forward<D>.
— end note]
Postconditions: get() yields the value u.get() yielded before the construction.
u.get() == nullptr.
get_deleter() returns a reference to the stored deleter that was constructed from u.get_deleter().
If D is a reference type then get_deleter() and u.get_deleter() both reference the same lvalue deleter.
template<class U, class E> constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
Constraints:
  • unique_ptr<U, E>​::​pointer is implicitly convertible to pointer,
  • U is not an array type, and
  • either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.
Preconditions: If E is not a reference type, construction of the deleter from an rvalue of type E is well-formed and does not throw an exception.
Otherwise, E is a reference type and construction of the deleter from an lvalue of type E is well-formed and does not throw an exception.
Effects: Constructs a unique_ptr from u.
If E is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
[Note 2: 
The deleter constructor can be implemented with std​::​forward<E>.
— end note]
Postconditions: get() yields the value u.get() yielded before the construction.
u.get() == nullptr.
get_deleter() returns a reference to the stored deleter that was constructed from u.get_deleter().

20.3.1.3.3 Destructor [unique.ptr.single.dtor]

constexpr ~unique_ptr();
Effects: Equivalent to: if (get()) get_deleter()(get());
[Note 1: 
The use of default_delete requires T to be a complete type.
— end note]
Remarks: The behavior is undefined if the evaluation of get_deleter()(get()) throws an exception.

20.3.1.3.4 Assignment [unique.ptr.single.asgn]

constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;
Constraints: is_move_assignable_v<D> is true.
Preconditions: If D is not a reference type, D meets the Cpp17MoveAssignable requirements (Table 33) and assignment of the deleter from an rvalue of type D does not throw an exception.
Otherwise, D is a reference type; remove_reference_t<D> meets the Cpp17CopyAssignable requirements and assignment of the deleter from an lvalue of type D does not throw an exception.
Effects: Calls reset(u.release()) followed by get_deleter() = std​::​forward<D>(u.get_deleter()).
Postconditions: If this != addressof(u), u.get() == nullptr, otherwise u.get() is unchanged.
Returns: *this.
template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
Constraints:
  • unique_ptr<U, E>​::​pointer is implicitly convertible to pointer, and
  • U is not an array type, and
  • is_assignable_v<D&, E&&> is true.
Preconditions: If E is not a reference type, assignment of the deleter from an rvalue of type E is well-formed and does not throw an exception.
Otherwise, E is a reference type and assignment of the deleter from an lvalue of type E is well-formed and does not throw an exception.
Effects: Calls reset(u.release()) followed by get_deleter() = std​::​forward<E>(u.get_deleter()).
Postconditions: u.get() == nullptr.
Returns: *this.
constexpr unique_ptr& operator=(nullptr_t) noexcept;
Effects: As if by reset().
Postconditions: get() == nullptr.
Returns: *this.

20.3.1.3.5 Observers [unique.ptr.single.observers]

constexpr add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));
Preconditions: get() != nullptr.
Returns: *get().
constexpr pointer operator->() const noexcept;
Preconditions: get() != nullptr.
Returns: get().
[Note 1: 
The use of this function typically requires that T be a complete type.
— end note]
constexpr pointer get() const noexcept;
Returns: The stored pointer.
constexpr deleter_type& get_deleter() noexcept; constexpr const deleter_type& get_deleter() const noexcept;
Returns: A reference to the stored deleter.
constexpr explicit operator bool() const noexcept;
Returns: get() != nullptr.

20.3.1.3.6 Modifiers [unique.ptr.single.modifiers]

constexpr pointer release() noexcept;
Postconditions: get() == nullptr.
Returns: The value get() had at the start of the call to release.
constexpr void reset(pointer p = pointer()) noexcept;
Effects: Assigns p to the stored pointer, and then, with the old value of the stored pointer, old_p, evaluates if (old_p) get_deleter()(old_p);
[Note 1: 
The order of these operations is significant because the call to get_deleter() might destroy *this.
— end note]
Postconditions: get() == p.
[Note 2: 
The postcondition does not hold if the call to get_deleter() destroys *this since this->get() is no longer a valid expression.
— end note]
Remarks: The behavior is undefined if the evaluation of get_deleter()(old_p) throws an exception.
constexpr void swap(unique_ptr& u) noexcept;
Preconditions: get_deleter() is swappable ([swappable.requirements]) and does not throw an exception under swap.
Effects: Invokes swap on the stored pointers and on the stored deleters of *this and u.