20 General utilities library [utilities] (original) (raw)

20.11 Smart pointers [smartptr]

20.11.1 Class template unique_­ptr [unique.ptr]

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.

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

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.

Each object of a type U instantiated from the unique_­ptr template specified in this subclause has the strict ownership semantics, specified above, of a unique pointer.

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

The template parameter T of unique_­ptr may be an incomplete type.

[ Note

:

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.11.1.1 Default deleters [unique.ptr.dltr]

20.11.1.1.1 In general [unique.ptr.dltr.general]

The class template default_­delete serves as the default deleter (destruction policy) for the class template unique_­ptr.

The template parameter T of default_­delete may be an incomplete type.

20.11.1.1.2 default_­delete [unique.ptr.dltr.dflt]

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

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

Constraints: U* is implicitly convertible to T*.

Effects:Constructs a default_­delete object from another default_­delete<U> object.

void operator()(T* ptr) const;

Mandates: T is a complete type.

Effects:Calls delete on ptr.

20.11.1.1.3 default_­delete<T[]> [unique.ptr.dltr.dflt1]

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

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

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

Effects:Constructs a default_­delete object from another default_­delete<U[]> object.

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

Mandates: U is a complete type.

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

Effects:Calls delete[] on ptr.

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

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;

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();


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;


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;


pointer release() noexcept;
void reset(pointer p = pointer()) noexcept;
void swap(unique_ptr& u) noexcept;


unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;

}; }

The default type for the template parameter D isdefault_­delete.

A client-supplied template argumentD shall be afunction object type, 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.

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.

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 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_­pointermay 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 andis_­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 andis_­default_­constructible_­v<deleter_­type> is true.

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

Effects:Constructs a unique_­ptr which ownsp, 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.

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());
unique_ptr<int, D> p2(new int, d);
unique_ptr<int, D&> p3(new int, d);
unique_ptr<int, const D&> p4(new int, D());

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 Cpp17MoveConstructiblerequirements (Table 28).

Construction of the deleter from an rvalue of type D does not throw an exception.

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

:

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 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> unique_ptr(unique_ptr<U, E>&& u) noexcept;

Constraints:

Preconditions:If E is not a reference type, construction of the deleter from an rvalue of type Eis well-formed and does not throw an exception.

Otherwise, E is a reference type and construction of the deleter from an lvalue of type Eis 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 fromu's deleter; otherwise, this deleter is move constructed from u's deleter.

[ Note

:

The deleter constructor can be implemented withstd​::​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 fromu.get_­deleter().

20.11.1.2.2 Destructor [unique.ptr.single.dtor]

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 theCpp17MoveAssignable 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 Cpp17CopyAssignablerequirements and assignment of the deleter from an lvalue of type D does not throw an exception.

Effects:Calls reset(u.release()) followed byget_­deleter() = std​::​forward<D>(u.get_­deleter()).

Postconditions: u.get() == nullptr.

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

Constraints:

Preconditions:If E is not a reference type, assignment of the deleter from an rvalue of type Eis well-formed and does not throw an exception.

Otherwise, E is a reference type and assignment of the deleter from an lvalue of type Eis well-formed and does not throw an exception.

Effects:Calls reset(u.release()) followed byget_­deleter() = std​::​forward<E>(u.get_­deleter()).

Postconditions: u.get() == nullptr.

unique_ptr& operator=(nullptr_t) noexcept;

Effects:As if by reset().

Postconditions: get() == nullptr.

20.11.1.2.4 Observers [unique.ptr.single.observers]

add_lvalue_reference_t<T> operator*() const;

Preconditions: get() != nullptr.

pointer operator->() const noexcept;

Preconditions: get() != nullptr.

[ 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, callsget_­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;

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

20.11.1.3 unique_­ptr for array objects with a runtime length [unique.ptr.runtime]

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;

constexpr unique_ptr() noexcept;
template<class U> explicit unique_ptr(U p) noexcept;
template<class U> unique_ptr(U p, see below d) noexcept;
template<class U> unique_ptr(U p, see below d) noexcept;
unique_ptr(unique_ptr&& u) noexcept;
template<class U, class E>
  unique_ptr(unique_ptr<U, E>&& u) noexcept;
constexpr unique_ptr(nullptr_t) noexcept;


~unique_ptr();


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;


T& operator[](size_t i) const;
pointer get() const noexcept;
deleter_type& get_deleter() noexcept;
const deleter_type& get_deleter() const noexcept;
explicit operator bool() const noexcept;


pointer release() noexcept;
template<class U> void reset(U p) noexcept;
void reset(nullptr_t = nullptr) noexcept;
void swap(unique_ptr& u) noexcept;


unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;

}; }

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

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

The template argument T shall be a complete type.

20.11.1.3.1 Constructors [unique.ptr.runtime.ctor]

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

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

Constraints:

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

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

Constraints:

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

This constructor behaves the same as in the primary template.

Constraints:Where UP is unique_­ptr<U, E>:

[ Note

:

This replaces the Constraints: specification of the primary template.

end note

]

20.11.1.3.2 Assignment [unique.ptr.runtime.asgn]

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

This operator behaves the same as in the primary template.

Constraints:Where UP is unique_­ptr<U, E>:

[ Note

:

This replaces the Constraints: specification of the primary template.

end note

]

20.11.1.3.3 Observers [unique.ptr.runtime.observers]

T& operator[](size_t i) const;

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

20.11.1.3.4 Modifiers [unique.ptr.runtime.modifiers]

void reset(nullptr_t p = nullptr) noexcept;

Effects:Equivalent to reset(pointer()).

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

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

Constraints:

20.11.1.4 Creation [unique.ptr.create]

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

Constraints: T is not an array type.

Returns: unique_­ptr<T>(new T(std​::​forward<Args>(args)...)).

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

Constraints: T is an array of unknown bound.

Returns: unique_­ptr<T>(new remove_­extent_­t<T>[n]()).

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

Constraints: T is an array of known bound.

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

Constraints: T is not an array type.

Returns: unique_­ptr<T>(new T).

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

Constraints: T is an array of unknown bound.

Returns: unique_­ptr<T>(new remove_­extent_­t<T>[n]).

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

Constraints: T is an array of known bound.

20.11.1.5 Specialized algorithms [unique.ptr.special]

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

Constraints: is_­swappable_­v<D> is true.

Effects:Calls x.swap(y).

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

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

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

Let CT denote

common_type_t<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer>

Mandates:

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

Returns: less<CT>()(x.get(), y.get()).

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

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

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

template<class T1, class D1, class T2, class D2> requires three_­way_­comparable_­with<typename unique_ptr<T1, D1>::pointer,typename unique_ptr<T2, D2>::pointer> 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);

Returns: compare_­three_­way()(x.get(), y.get()).

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

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

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.

Returns:The first function template returns

less<unique_ptr<T, D>::pointer>()(x.get(), nullptr)

The second function template returns

less<unique_ptr<T, D>::pointer>()(nullptr, x.get())

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

Returns:The first function template returns nullptr < x.

The second function template returns x < nullptr.

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

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

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

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

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

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

template<class T, class D> requires three_­way_­comparable_­with<typename unique_ptr<T, D>::pointer, nullptr_t> compare_three_way_result_t<typename unique_ptr<T, D>::pointer, nullptr_t> operator<=>(const unique_ptr<T, D>& x, nullptr_t);

Returns: compare_­three_­way()(x.get(), nullptr).

20.11.1.6 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);

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

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

20.11.2 Class bad_­weak_­ptr [util.smartptr.weak.bad]

namespace std { class bad_weak_ptr : public exception { public:

const char* what() const noexcept override;

}; }

An exception of type bad_­weak_­ptr is thrown by the shared_­ptrconstructor taking a weak_­ptr.

const char* what() const noexcept override;

Returns:An implementation-defined ntbs.

20.11.4 Class template weak_­ptr [util.smartptr.weak]

The weak_­ptr class template stores a weak reference to an object that is already managed by a shared_­ptr.

To access the object, aweak_­ptr can be converted to a shared_­ptr using the member function lock.

namespace std { template class weak_ptr { public: using element_type = remove_extent_t;

constexpr weak_ptr() noexcept;
template<class Y>
  weak_ptr(const shared_ptr<Y>& r) noexcept;
weak_ptr(const weak_ptr& r) noexcept;
template<class Y>
  weak_ptr(const weak_ptr<Y>& r) noexcept;
weak_ptr(weak_ptr&& r) noexcept;
template<class Y>
  weak_ptr(weak_ptr<Y>&& r) noexcept;


~weak_ptr();


weak_ptr& operator=(const weak_ptr& r) noexcept;
template<class Y>
  weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
template<class Y>
  weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
weak_ptr& operator=(weak_ptr&& r) noexcept;
template<class Y>
  weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;


void swap(weak_ptr& r) noexcept;
void reset() noexcept;


long use_count() const noexcept;
bool expired() const noexcept;
shared_ptr<T> lock() const noexcept;
template<class U>
  bool owner_before(const shared_ptr<U>& b) const noexcept;
template<class U>
  bool owner_before(const weak_ptr<U>& b) const noexcept;

};

template weak_ptr(shared_ptr) -> weak_ptr;

template void swap(weak_ptr& a, weak_ptr& b) noexcept; }

Specializations of weak_­ptr shall be Cpp17CopyConstructible andCpp17CopyAssignable, allowing their use in standard containers.

The template parameter T of weak_­ptr may be an incomplete type.

20.11.4.1 Constructors [util.smartptr.weak.const]

constexpr weak_ptr() noexcept;

Effects:Constructs an empty weak_­ptr object.

Postconditions: use_­count() == 0.

weak_ptr(const weak_ptr& r) noexcept;template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;

Constraints:For the second and third constructors, Y* is compatible with T*.

Effects:If r is empty, constructs an empty weak_­ptr object; otherwise, constructs a weak_­ptr object that shares ownership with r and stores a copy of the pointer stored in r.

Postconditions: use_­count() == r.use_­count().

weak_ptr(weak_ptr&& r) noexcept;template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;

Constraints:For the second constructor, Y* is compatible with T*.

Effects:Move constructs a weak_­ptr instance from r.

Postconditions: *this shall contain the old value of r.

r shall be empty.

r.use_­count() == 0.

20.11.4.2 Destructor [util.smartptr.weak.dest]

Effects:Destroys this weak_­ptr object but has no effect on the object its stored pointer points to.

20.11.4.3 Assignment [util.smartptr.weak.assign]

weak_ptr& operator=(const weak_ptr& r) noexcept;template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;

Effects:Equivalent to weak_­ptr(r).swap(*this).

Remarks:The implementation may meet the effects (and the implied guarantees) via different means, without creating a temporary object.

weak_ptr& operator=(weak_ptr&& r) noexcept;template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;

Effects:Equivalent to weak_­ptr(std​::​move(r)).swap(*this).

20.11.4.4 Modifiers [util.smartptr.weak.mod]

void swap(weak_ptr& r) noexcept;

Effects:Exchanges the contents of *this and r.

Effects:Equivalent to weak_­ptr().swap(*this).

20.11.4.5 Observers [util.smartptr.weak.obs]

long use_count() const noexcept;

Returns: 0 if *this is empty; otherwise, the number of shared_­ptr instances that share ownership with *this.

bool expired() const noexcept;

Returns: use_­count() == 0.

shared_ptr<T> lock() const noexcept;

Returns: expired() ? shared_­ptr<T>() : shared_­ptr<T>(*this), executed atomically.

template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;

Returns:An unspecified value such that

20.11.4.6 Specialized algorithms [util.smartptr.weak.spec]

template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;

Effects:Equivalent to a.swap(b).

20.11.5 Class template owner_­less [util.smartptr.ownerless]

The class template owner_­less allows ownership-based mixed comparisons of shared and weak pointers.

namespace std { template struct owner_less;

template struct owner_less<shared_ptr> { bool operator()(const shared_ptr&, const shared_ptr&) const noexcept; bool operator()(const shared_ptr&, const weak_ptr&) const noexcept; bool operator()(const weak_ptr&, const shared_ptr&) const noexcept; };

template struct owner_less<weak_ptr> { bool operator()(const weak_ptr&, const weak_ptr&) const noexcept; bool operator()(const shared_ptr&, const weak_ptr&) const noexcept; bool operator()(const weak_ptr&, const shared_ptr&) const noexcept; };

template<> struct owner_less { template<class T, class U> bool operator()(const shared_ptr&, const shared_ptr&) const noexcept; template<class T, class U> bool operator()(const shared_ptr&, const weak_ptr&) const noexcept; template<class T, class U> bool operator()(const weak_ptr&, const shared_ptr&) const noexcept; template<class T, class U> bool operator()(const weak_ptr&, const weak_ptr&) const noexcept;

using is_transparent = unspecified;

}; }

operator()(x, y) returns x.owner_­before(y).

[ Note

:

Note that

end note

]

20.11.6 Class template enable_­shared_­from_­this [util.smartptr.enab]

A class T can inherit from enable_­shared_­from_­this<T>to inherit the shared_­from_­this member functions that obtain a shared_­ptr instance pointing to *this.

[ Example

:

struct X: public enable_shared_from_this { };

int main() { shared_ptr p(new X); shared_ptr q = p->shared_from_this(); assert(p == q); assert(!p.owner_before(q) && !q.owner_before(p)); }

end example

]

namespace std { template class enable_shared_from_this { protected: constexpr enable_shared_from_this() noexcept; enable_shared_from_this(const enable_shared_from_this&) noexcept; enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept; ~enable_shared_from_this();

public: shared_ptr shared_from_this(); shared_ptr shared_from_this() const; weak_ptr weak_from_this() noexcept; weak_ptr weak_from_this() const noexcept;

private: mutable weak_ptr weak_this;
}; }

The template parameter T of enable_­shared_­from_­thismay be an incomplete type.

constexpr enable_shared_from_this() noexcept; enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;

Effects:Value-initializes weak_­this.

enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;

[ Note

:

weak_­this is not changed.

end note

]

shared_ptr<T> shared_from_this(); shared_ptr<T const> shared_from_this() const;

Returns: shared_­ptr<T>(weak_­this).

weak_ptr<T> weak_from_this() noexcept; weak_ptr<T const> weak_from_this() const noexcept;

20.11.7 Smart pointer hash support [util.smartptr.hash]

template<class T, class D> struct hash<unique_ptr<T, D>>;

Letting UP be unique_­ptr<T,D>, the specialization hash<UP> is enabled ([unord.hash]) if and only if hash<typename UP​::​pointer> is enabled.

When enabled, for an object p of type UP,hash<UP>()(p) evaluates to the same value as hash<typename UP​::​pointer>()(p.get()).

The member functions are not guaranteed to be noexcept.

template<class T> struct hash<shared_ptr<T>>;

For an object p of type shared_­ptr<T>,hash<shared_­ptr<T>>()(p) evaluates to the same value as hash<typename shared_­ptr<T>​::​element_­type*>()(p.get()).