20 General utilities library [utilities]

20.11 Smart pointers [smartptr]

20.11.1 Class template unique_­ptr [unique.ptr]

20.11.1.2 unique_­ptr for single objects [unique.ptr.single]

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;
    explicit unique_ptr(pointer p) noexcept;
    unique_ptr(pointer p, see below d1) noexcept;
    unique_ptr(pointer p, see below d2) noexcept;
    unique_ptr(unique_ptr&& u) noexcept;
    constexpr unique_ptr(nullptr_t) noexcept;
    template<class U, class E>
      unique_ptr(unique_ptr<U, E>&& u) noexcept;

    // [unique.ptr.single.dtor], destructor
    ~unique_ptr();

    // [unique.ptr.single.asgn], assignment
    unique_ptr& operator=(unique_ptr&& u) noexcept;
    template<class U, class E>
      unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
    unique_ptr& operator=(nullptr_t) noexcept;

    // [unique.ptr.single.observers], observers
    add_lvalue_reference_t<T> operator*() const;
    pointer operator->() const noexcept;
    pointer get() const noexcept;
    deleter_type& get_deleter() noexcept;
    const deleter_type& get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    // [unique.ptr.single.modifiers], modifiers
    pointer release() noexcept;
    void reset(pointer p = pointer()) noexcept;
    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, 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 32).
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 33).
Example
:
Given an allocator type X (Table 36) 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.11.1.2.1 Constructors [unique.ptr.single.ctor]

constexpr unique_ptr() noexcept; constexpr unique_ptr(nullptr_t) noexcept;
Preconditions: D meets the Cpp17DefaultConstructible requirements (Table 27), and that construction does not throw an exception.
Constraints: is_­pointer_­v<deleter_­type> is false and is_­default_­constructible_­v<deleter_­type> is true.
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.
explicit unique_ptr(pointer p) noexcept;
Constraints: is_­pointer_­v<deleter_­type> is false and is_­default_­constructible_­v<deleter_­type> is true.
Mandates: This constructor is not selected by class template argument deduction ([over.match.class.deduct]).
Preconditions: D meets the Cpp17DefaultConstructible requirements (Table 27), 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.
unique_ptr(pointer p, const D& d) noexcept; unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept;
Constraints: is_­constructible_­v<D, decltype(d)> is true.
Mandates: These constructors are not selected by class template argument deduction ([over.match.class.deduct]).
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
:
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
 ]
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 28).
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
:
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> 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
:
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.11.1.2.2 Destructor [unique.ptr.single.dtor]

~unique_ptr();
Preconditions: The expression get_­deleter()(get()) is well-formed, has well-defined behavior, and does not throw exceptions.
Note
:
The use of default_­delete requires T to be a complete type.
— end note
 ]
Effects: If get() == nullptr there are no effects.
Otherwise get_­deleter()(get()).

20.11.1.2.3 Assignment [unique.ptr.single.asgn]

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 30) 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()).
Returns: *this.
Postconditions: u.get() == nullptr.
template<class U, class E> 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()).
Returns: *this.
Postconditions: u.get() == nullptr.
unique_ptr& operator=(nullptr_t) noexcept;
Effects: As if by reset().
Postconditions: get() == nullptr.
Returns: *this.

20.11.1.2.4 Observers [unique.ptr.single.observers]

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

20.11.1.2.5 Modifiers [unique.ptr.single.modifiers]

pointer release() noexcept;
Postconditions: get() == nullptr.
Returns: The value get() had at the start of the call to release.
void reset(pointer p = pointer()) noexcept;
Preconditions: The expression get_­deleter()(get()) is well-formed, has well-defined behavior, and does not throw exceptions.
Effects: Assigns p to the stored pointer, and then if and only if the old value of the stored pointer, old_­p, was not equal to nullptr, calls get_­deleter()(old_­p).
Note
:
The order of these operations is significant because the call to get_­deleter() may destroy *this.
— end note
 ]
Postconditions: get() == p.
Note
:
The postcondition does not hold if the call to get_­deleter() destroys *this since this->get() is no longer a valid expression.
— end note
 ]
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.