Files
cppdraft_translate/cppdraft/unique/ptr.md
2025-10-25 03:02:53 +03:00

52 KiB
Raw Blame History

[unique.ptr]

20 Memory management library [mem]

20.3 Smart pointers [smartptr]

20.3.1 Unique-ownership pointers [unique.ptr]

20.3.1.1 General [unique.ptr.general]

1

#

A unique pointer is an object that owns another object and manages that other object through a pointer.

More precisely, a unique pointer is an object u that stores a pointer to a second object p and will dispose of p when u is itself destroyed (e.g., when leaving block scope ([stmt.dcl])).

In this context, u is said to own p.

2

#

The mechanism by which u disposes of p is known asp's associated deleter, a function object whose correct invocation results in p's appropriate disposition (typically its deletion).

3

#

Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter.

Upon request, u canreset (replace) u.p and u.d with another pointer and deleter, but properly disposes of its owned object via the associated deleter before such replacement is considered completed.

4

#

Each object of a type U instantiated from the unique_ptr template specified in [unique.ptr] has the strict ownership semantics, specified above, of a unique pointer.

In partial satisfaction of these semantics, each such U is Cpp17MoveConstructible and Cpp17MoveAssignable, but is notCpp17CopyConstructible nor Cpp17CopyAssignable.

The template parameter T of unique_ptr may be an incomplete type.

5

#

[Note 1:

The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from a function.

— end note]

20.3.1.2 Default deleters [unique.ptr.dltr]

20.3.1.2.1 General [unique.ptr.dltr.general]

1

#

The class template default_delete serves as the default deleter (destruction policy) for the class template unique_ptr.

2

#

The template parameter T of default_delete may be an incomplete type.

20.3.1.2.2 default_delete [unique.ptr.dltr.dflt]

namespace std {template struct default_delete {constexpr default_delete() noexcept = default; template constexpr default_delete(const default_delete&) noexcept; constexpr void operator()(T*) const; };}

🔗

template<class U> constexpr default_delete(const default_delete<U>& other) noexcept;

1

#

Constraints: U* is implicitly convertible to T*.

2

#

Effects: Constructs a default_delete object from another default_delete object.

🔗

constexpr void operator()(T* ptr) const;

3

#

Mandates: T is a complete type.

4

#

Effects: Calls delete on ptr.

20.3.1.2.3 default_delete<T[]> [unique.ptr.dltr.dflt1]

namespace std {template struct default_delete<T[]> {constexpr default_delete() noexcept = default; template constexpr default_delete(const default_delete<U[]>&) noexcept; template constexpr void operator()(U* ptr) const; };}

🔗

template<class U> constexpr default_delete(const default_delete<U[]>& other) noexcept;

1

#

Constraints: U()[] is convertible to T()[].

2

#

Effects: Constructs a default_delete object from another default_delete<U[]> object.

🔗

template<class U> constexpr void operator()(U* ptr) const;

3

#

Constraints: U()[] is convertible to T()[].

4

#

Mandates: U is a complete type.

5

#

Effects: Calls delete[] on 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> class unique_ptr {public:using pointer = see below; using element_type = T; using deleter_type = D; // [unique.ptr.single.ctor], constructorsconstexpr unique_ptr() noexcept; constexpr explicit unique_ptr(type_identity_t p) noexcept; constexpr unique_ptr(type_identity_t p, see below d1) noexcept; constexpr unique_ptr(type_identity_t 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], destructorconstexpr ~unique_ptr(); // [unique.ptr.single.asgn], assignmentconstexpr 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], observersconstexpr add_lvalue_reference_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], modifiersconstexpr 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; };}

1

#

A program that instantiates the definition of unique_ptr<T, D> is ill-formed if T* is an invalid type.

[Note 1:

This prevents the instantiation of specializations such asunique_ptr<T&, D> and unique_ptr<int() const, D>.

— end note]

2

#

The default type for the template parameter D isdefault_delete.

A client-supplied template argumentD 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 valueptr of type unique_ptr<T, D>::pointer, the expressiond(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.

3

#

If the deleter's type D is not a reference type, D shall meet the Cpp17Destructible requirements (Table 35).

4

#

If the qualified-id remove_reference_t::pointer is valid and denotes a type ([temp.deduct]), then unique_ptr<T, D>::pointer shall be a synonym for remove_reference_t::pointer.

Otherwiseunique_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).

5

#

[Example 1:

Given an allocator type X ([allocator.requirements.general]) and letting A be a synonym for allocator_traits, 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;

1

#

Constraints: is_pointer_v<deleter_type> is false andis_default_constructible_v<deleter_type> is true.

2

#

Preconditions: D meets the Cpp17DefaultConstructible requirements (Table 30), and that construction does not throw an exception.

3

#

Effects: Constructs a unique_ptr object that owns nothing, value-initializing the stored pointer and the stored deleter.

4

#

Postconditions: get() == nullptr.

get_deleter() returns a reference to the stored deleter.

🔗

constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept;

5

#

Constraints: is_pointer_v<deleter_type> is false andis_default_constructible_v<deleter_type> is true.

6

#

Preconditions: D meets the Cpp17DefaultConstructible requirements (Table 30), and that construction does not throw an exception.

7

#

Effects: Constructs a unique_ptr which ownsp, initializing the stored pointer with p and value-initializing the stored deleter.

8

#

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;

9

#

Constraints: is_constructible_v<D, decltype(d)> is true.

10

#

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.

11

#

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).

12

#

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.

13

#

Remarks: If D is a reference type, the second constructor is defined as deleted.

14

#

[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;

15

#

Constraints: is_move_constructible_v is true.

16

#

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.

17

#

Effects: Constructs a unique_ptr fromu.

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.

— end note]

18

#

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 fromu.get_deleter().

If D is a reference type thenget_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;

19

#

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, orD is not a reference type and E is implicitly convertible to D.

20

#

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.

21

#

Effects: Constructs a unique_ptr from u.

If E is a reference type, this deleter is copy constructed fromu's deleter; otherwise, this deleter is move constructed from u's deleter.

[Note 2:

The deleter constructor can be implemented withstd::forward.

— end note]

22

#

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 fromu.get_deleter().

20.3.1.3.3 Destructor [unique.ptr.single.dtor]

🔗

constexpr ~unique_ptr();

1

#

Effects: Equivalent to:if (get()) get_deleter()(get());

[Note 1:

The use of default_delete requires T to be a complete type.

— end note]

2

#

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;

1

#

Constraints: is_move_assignable_v is true.

2

#

Preconditions: If D is not a reference type, D meets theCpp17MoveAssignable 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 meets the Cpp17CopyAssignable requirements and assignment of the deleter from an lvalue of type D does not throw an exception.

3

#

Effects: Calls reset(u.release()) followed byget_deleter() = std::forward(u.get_deleter()).

4

#

Postconditions: If this != addressof(u),u.get() == nullptr, otherwise u.get() is unchanged.

5

#

Returns: *this.

🔗

template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;

6

#

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.

7

#

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.

8

#

Effects: Calls reset(u.release()) followed byget_deleter() = std::forward(u.get_deleter()).

9

#

Postconditions: u.get() == nullptr.

10

#

Returns: *this.

🔗

constexpr unique_ptr& operator=(nullptr_t) noexcept;

11

#

Effects: As if by reset().

12

#

Postconditions: get() == nullptr.

13

#

Returns: *this.

20.3.1.3.5 Observers [unique.ptr.single.observers]

🔗

constexpr add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));

1

#

Mandates: reference_converts_from_temporary_v<add_lvalue_reference_t, decltype(
*declval())> is false.

2

#

Preconditions: get() != nullptr is true.

3

#

Returns: *get().

🔗

constexpr pointer operator->() const noexcept;

4

#

Preconditions: get() != nullptr.

5

#

Returns: get().

6

#

[Note 1:

The use of this function typically requires that T be a complete type.

— end note]

🔗

constexpr pointer get() const noexcept;

7

#

Returns: The stored pointer.

🔗

constexpr deleter_type& get_deleter() noexcept; constexpr const deleter_type& get_deleter() const noexcept;

8

#

Returns: A reference to the stored deleter.

🔗

constexpr explicit operator bool() const noexcept;

9

#

Returns: get() != nullptr.

20.3.1.3.6 Modifiers [unique.ptr.single.modifiers]

🔗

constexpr pointer release() noexcept;

1

#

Postconditions: get() == nullptr.

2

#

Returns: The value get() had at the start of the call to release.

🔗

constexpr void reset(pointer p = pointer()) noexcept;

3

#

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]

4

#

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]

5

#

Remarks: The behavior is undefined if the evaluation of get_deleter()(old_p) throws an exception.

🔗

constexpr void swap(unique_ptr& u) noexcept;

6

#

Preconditions: get_deleter() is swappable ([swappable.requirements]) and does not throw an exception under swap.

7

#

Effects: Invokes swap on the stored pointers and on the stored deleters of *this and u.

20.3.1.4 unique_ptr for array objects with a runtime length [unique.ptr.runtime]

20.3.1.4.1 General [unique.ptr.runtime.general]

🔗

namespace std {template<class T, class D> class unique_ptr<T[], D> {public:using pointer = see below; using element_type = T; using deleter_type = D; // [unique.ptr.runtime.ctor], constructorsconstexpr unique_ptr() noexcept; template constexpr explicit unique_ptr(U p) noexcept; template constexpr unique_ptr(U p, see below d) noexcept; template constexpr unique_ptr(U p, see below d) noexcept; constexpr unique_ptr(unique_ptr&& u) noexcept; template<class U, class E>constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; // destructorconstexpr ~unique_ptr(); // assignmentconstexpr 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.runtime.observers], observersconstexpr T& operator[](size_t i) const; 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.runtime.modifiers], modifiersconstexpr pointer release() noexcept; template constexpr void reset(U p) noexcept; constexpr void reset(nullptr_t = nullptr) 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; };}

1

#

A specialization for array types is provided with a slightly altered interface.

  • (1.1)

    Conversions between different types ofunique_ptr<T[], D> that would be disallowed for the corresponding pointer-to-array types, and conversions to or from the non-array forms ofunique_ptr, produce an ill-formed program.

  • (1.2)

    Pointers to types derived from T are rejected by the constructors, and by reset.

  • (1.3)

    The observers operator* andoperator-> are not provided.

  • (1.4)

    The indexing observer operator[] is provided.

  • (1.5)

    The default deleter will call delete[].

2

#

Descriptions are provided below only for members that differ from the primary template.

3

#

The template argument T shall be a complete type.

20.3.1.4.2 Constructors [unique.ptr.runtime.ctor]

🔗

template<class U> constexpr explicit unique_ptr(U p) noexcept;

1

#

This constructor behaves the same as the constructor in the primary template that takes a single parameter of type pointer.

2

#

Constraints:

U is the same type as pointer, or

pointer is the same type as element_type*,U is a pointer type V*, andV()[] is convertible to element_type()[].

🔗

template<class U> constexpr unique_ptr(U p, see below d) noexcept; template<class U> constexpr unique_ptr(U p, see below d) noexcept;

3

#

These constructors behave the same as the constructors in the primary template that take a parameter of type pointer and a second parameter.

4

#

Constraints:

U is the same type as pointer,

U is nullptr_t, or

pointer is the same type as element_type*, U is a pointer type V*, and V()[] is convertible to element_type()[].

🔗

template<class U, class E> constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;

5

#

This constructor behaves the same as in the primary template.

6

#

Constraints: Where UP is unique_ptr<U, E>:

U is an array type, and

pointer is the same type as element_type*, and

UP::pointer is the same type as UP::element_type*, and

UP::element_type()[] is convertible to element_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.

[Note 1:

This replaces the Constraints: specification of the primary template.

— end note]

20.3.1.4.3 Assignment [unique.ptr.runtime.asgn]

🔗

template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;

1

#

This operator behaves the same as in the primary template.

2

#

Constraints: Where UP is unique_ptr<U, E>:

U is an array type, and

pointer is the same type as element_type*, and

UP::pointer is the same type as UP::element_type*, and

UP::element_type()[] is convertible to element_type()[], and

is_assignable_v<D&, E&&> is true.

[Note 1:

This replaces the Constraints: specification of the primary template.

— end note]

20.3.1.4.4 Observers [unique.ptr.runtime.observers]

🔗

constexpr T& operator[](size_t i) const;

1

#

Preconditions: i < the number of elements in the array to which the stored pointer points.

2

#

Returns: get()[i].

20.3.1.4.5 Modifiers [unique.ptr.runtime.modifiers]

🔗

constexpr void reset(nullptr_t p = nullptr) noexcept;

1

#

Effects: Equivalent to reset(pointer()).

🔗

template<class U> constexpr void reset(U p) noexcept;

2

#

This function behaves the same as the reset member of the primary template.

3

#

Constraints:

U is the same type as pointer, or

pointer is the same type as element_type*, U is a pointer type V*, and V()[] is convertible to element_type()[].

20.3.1.5 Creation [unique.ptr.create]

🔗

template<class T, class... Args> constexpr unique_ptr<T> make_unique(Args&&... args);

1

#

Constraints: T is not an array type.

2

#

Returns: unique_ptr(new T(std::forward(args)...)).

🔗

template<class T> constexpr unique_ptr<T> make_unique(size_t n);

3

#

Constraints: T is an array of unknown bound.

4

#

Returns: unique_ptr(new remove_extent_tn).

🔗

template<class T, class... Args> unspecified make_unique(Args&&...) = delete;

5

#

Constraints: T is an array of known bound.

🔗

template<class T> constexpr unique_ptr<T> make_unique_for_overwrite();

6

#

Constraints: T is not an array type.

7

#

Returns: unique_ptr(new T).

🔗

template<class T> constexpr unique_ptr<T> make_unique_for_overwrite(size_t n);

8

#

Constraints: T is an array of unknown bound.

9

#

Returns: unique_ptr(new remove_extent_t[n]).

🔗

template<class T, class... Args> unspecified make_unique_for_overwrite(Args&&...) = delete;

10

#

Constraints: T is an array of known bound.

20.3.1.6 Specialized algorithms [unique.ptr.special]

🔗

template<class T, class D> constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;

1

#

Constraints: is_swappable_v is true.

2

#

Effects: Calls x.swap(y).

🔗

template<class T1, class D1, class T2, class D2> constexpr bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

3

#

Returns: x.get() == y.get().

🔗

template<class T1, class D1, class T2, class D2> constexpr bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

4

#

Let CT denotecommon_type_t<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer>

5

#

Mandates:

unique_ptr<T1, D1>::pointer is implicitly convertible to CT and

unique_ptr<T2, D2>::pointer is implicitly convertible to CT.

6

#

Preconditions: The specializationless is a function object type ([function.objects]) that induces a strict weak ordering ([alg.sorting]) on the pointer values.

7

#

Returns: less()(x.get(), y.get()).

🔗

template<class T1, class D1, class T2, class D2> constexpr bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

8

#

Returns: y < x.

🔗

template<class T1, class D1, class T2, class D2> constexpr bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

9

#

Returns: !(y < x).

🔗

template<class T1, class D1, class T2, class D2> constexpr bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

10

#

Returns: !(x < y).

🔗

template<class T1, class D1, class T2, class D2> requires [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4Concept three_­way_­comparable[cmp.concept]")<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer> constexpr compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer> operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

11

#

Returns: compare_three_way()(x.get(), y.get()).

🔗

template<class T, class D> constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;

12

#

Returns: !x.

🔗

template<class T, class D> constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t); template<class T, class D> constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& x);

13

#

Preconditions: The specialization less<unique_ptr<T, D>::pointer> is a function object type ([function.objects]) that induces a strict weak ordering ([alg.sorting]) on the pointer values.

14

#

Returns: The first function template returnsless<unique_ptr<T, D>::pointer>()(x.get(), nullptr)

The second function template returnsless<unique_ptr<T, D>::pointer>()(nullptr, x.get())

🔗

template<class T, class D> constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t); template<class T, class D> constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& x);

15

#

Returns: The first function template returns nullptr < x.

The second function template returns x < nullptr.

🔗

template<class T, class D> constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t); template<class T, class D> constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& x);

16

#

Returns: The first function template returns !(nullptr < x).

The second function template returns !(x < nullptr).

🔗

template<class T, class D> constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t); template<class T, class D> constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& x);

17

#

Returns: The first function template returns !(x < nullptr).

The second function template returns !(nullptr < x).

🔗

template<class T, class D> requires [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4Concept three_­way_­comparable[cmp.concept]")<typename unique_ptr<T, D>::pointer> constexpr compare_three_way_result_t<typename unique_ptr<T, D>::pointer> operator<=>(const unique_ptr<T, D>& x, nullptr_t);

18

#

Returns: compare_three_way()(x.get(), static_cast<typename unique_ptr<T, D>::pointer>(nullptr)).

20.3.1.7 I/O [unique.ptr.io]

🔗

template<class E, class T, class Y, class D> basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const unique_ptr<Y, D>& p);

1

#

Constraints: os << p.get() is a valid expression.

2

#

Effects: Equivalent to: os << p.get();

3

#

Returns: os.