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 as p'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 can reset (replace) u.p and u.d with another pointer and deleter, but must properly dispose of its owned object via the associated deleter before such replacement is considered completed.
Additionally, u can, upon request, transfer ownership to another unique pointer u2. Upon completion of such a transfer, the following postconditions hold:
u2.p is equal to the pre-transfer u.p,
u.p is equal to nullptr, and
if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer associated deleter before the ownership transfer is considered complete. [ Note: A deleter's state need never be copied, only moved or swapped as ownership is transferred. — end note ]
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 U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable. 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 ]
namespace std { template<class T> struct default_delete; template<class T> struct default_delete<T[]>; template<class T, class D = default_delete<T>> class unique_ptr; template<class T, class D> class unique_ptr<T[], D>; template<class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; 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> 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 T, class D> bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; template <class T, class D> bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator!=(nullptr_t, const unique_ptr<T, D>& y) 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>& y); 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>& y); 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>& y); 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>& y); }
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.
namespace std { template <class T> struct default_delete { constexpr default_delete() noexcept = default; template <class U> default_delete(const default_delete<U>&) noexcept; void operator()(T*) const; }; }
template <class U> default_delete(const default_delete<U>& other) noexcept;
Effects: Constructs a default_delete object from another default_delete<U> object.
Remarks: This constructor shall not participate in overload resolution unless U* is implicitly convertible to T*.
void operator()(T *ptr) const;
Effects: calls delete on ptr.
Remarks: If T is an incomplete type, the program is ill-formed.
namespace std { template <class T> struct default_delete<T[]> { constexpr default_delete() noexcept = default; void operator()(T*) const; template <class U> void operator()(U*) const = delete; }; }
void operator()(T* ptr) const;
Effects: calls delete[] on ptr.
Remarks: If T is an incomplete type, the program is ill-formed.
namespace std { template <class T, class D = default_delete<T>> class unique_ptr { public: typedef see below pointer; typedef T element_type; typedef D deleter_type; // [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 : unique_ptr() { } template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept; template <class U> unique_ptr(auto_ptr<U>&& 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 typename add_lvalue_reference<T>::type 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 ([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 satisfy the requirements of Destructible (Table [destructible]).
If the type remove_reference<D>::type::pointer exists, then unique_ptr<T, D>::pointer shall be a synonym for remove_reference<D>::type::pointer. Otherwise unique_ptr<T, D>::pointer shall be a synonym for T*. The type unique_ptr<T, D>::pointer shall satisfy the requirements of NullablePointer ([nullablepointer.requirements]).
[ Example: Given an allocator type X ([allocator.requirements]) 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 ]
constexpr unique_ptr() noexcept;
Requires: D shall satisfy the requirements of DefaultConstructible (Table [defaultconstructible]), and that construction shall 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.
Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument D, the program is ill-formed.
explicit unique_ptr(pointer p) noexcept;
Requires: D shall satisfy the requirements of DefaultConstructible (Table [defaultconstructible]), and that construction shall 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.
Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument D, the program is ill-formed.
unique_ptr(pointer p, see below d1) noexcept;
unique_ptr(pointer p, see below d2) noexcept;
The signature of these constructors depends upon whether D is a reference type. If D is non-reference type A, then the signatures are:
unique_ptr(pointer p, const A& d); unique_ptr(pointer p, A&& d);
If D is an lvalue-reference type A&, then the signatures are:
unique_ptr(pointer p, A& d); unique_ptr(pointer p, A&& d);
If D is an lvalue-reference type const A&, then the signatures are:
unique_ptr(pointer p, const A& d); unique_ptr(pointer p, const A&& d);
Requires:
If D is not an lvalue-reference type then
If d is an lvalue or const rvalue then the first constructor of this pair will be selected. D shall satisfy the requirements of CopyConstructible (Table [copyconstructible]), and the copy constructor of D shall not throw an exception. This unique_ptr will hold a copy of d.
Otherwise, d is a non-const rvalue and the second constructor of this pair will be selected. D shall satisfy the requirements of MoveConstructible (Table [moveconstructible]), and the move constructor of D shall not throw an exception. This unique_ptr will hold a value move constructed from d.
Otherwise D is an lvalue-reference type. d shall be reference-compatible with one of the constructors. If d is an rvalue, it will bind to the second constructor of this pair and the program is ill-formed. [ Note: The diagnostic could be implemented using a static_assert which assures that D is not a reference type. — end note ] Else d is an lvalue and will bind to the first constructor of this pair. The type which D references need not be CopyConstructible nor MoveConstructible. This unique_ptr will hold a D which refers to the lvalue d. [ Note: D may not be an rvalue-reference type. — end note ]
Effects: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and initializing the deleter as described above.
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.
[ Example:
D d; unique_ptr<int, D> p1(new int, D()); // D must be MoveConstructible unique_ptr<int, D> p2(new int, d); // D must be CopyConstructible 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;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveConstructible (Table [moveconstructible]). Construction of the deleter from an rvalue of type D shall not throw an exception.
Effects: Constructs a unique_ptr by transferring ownership from u to *this. 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 deleter constructor can be implemented with std::forward<D>. — end note ]
Postconditions: get() yields the value u.get() yielded before the construction. 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;
Requires: If E is not a reference type, construction of the deleter from an rvalue of type E shall be well formed and shall not throw an exception. Otherwise, E is a reference type and construction of the deleter from an lvalue of type E shall be well formed and shall not throw an exception.
Remarks: This constructor shall not participate in overload resolution unless:
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.
Effects: Constructs a unique_ptr by transferring ownership from u to *this. 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. get_deleter() returns a reference to the stored deleter that was constructed from u.get_deleter().
template <class U>
unique_ptr(auto_ptr<U>&& u) noexcept;
Effects: Constructs a unique_ptr object, initializing the stored pointer with u.release() and value-initializing the stored deleter.
Postconditions: get() yields the value u.get() yielded before the construction. u.get() == nullptr. get_deleter() returns a reference to the stored deleter.
Remarks: This constructor shall not participate in overload resolution unless U* is implicitly convertible to T* and D is the same type as default_delete<T>.
Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior, and shall 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()).
unique_ptr& operator=(unique_ptr&& u) noexcept;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveAssignable (Table [moveassignable]) and assignment of the deleter from an rvalue of type D shall not throw an exception. Otherwise, D is a reference type; remove_reference<D>::type shall satisfy the CopyAssignable requirements and assignment of the deleter from an lvalue of type D shall not throw an exception.
Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by an assignment from std::forward<D>(u.get_deleter()).
Returns: *this.
template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
Requires: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be well-formed and shall not throw an exception. Otherwise, E is a reference type and assignment of the deleter from an lvalue of type E shall be well-formed and shall not throw an exception.
Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by an assignment from std::forward<D>(u.get_deleter()).
Returns: *this.
unique_ptr& operator=(nullptr_t) noexcept;
Effects: reset().
Postcondition: get() == nullptr
Returns: *this.
typename add_lvalue_reference<T>::type operator*() const;
Requires: get() != nullptr.
Returns: *get().
pointer operator->() const noexcept;
Requires: get() != nullptr.
Returns: get().
Note: use typically requires that T be a complete type.
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.
Postcondition: get() == nullptr.
Returns: The value get() had at the start of the call to release.
void reset(pointer p = pointer()) noexcept;
Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
Effects: assigns p to the stored pointer, and then 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;
Requires: get_deleter() shall be swappable ([swappable.requirements]) and shall not throw an exception under swap.
Effects: Invokes swap on the stored pointers and on the stored deleters of *this and u.
namespace std { template <class T, class D> class unique_ptr<T[], D> { public: typedef see below pointer; typedef T element_type; typedef D deleter_type; // [unique.ptr.runtime.ctor], constructors constexpr unique_ptr() noexcept; explicit unique_ptr(pointer p) noexcept; unique_ptr(pointer p, see below d) noexcept; unique_ptr(pointer p, see below d) noexcept; unique_ptr(unique_ptr&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } // destructor ~unique_ptr(); // assignment unique_ptr& operator=(unique_ptr&& u) noexcept; unique_ptr& operator=(nullptr_t) noexcept; // [unique.ptr.runtime.observers], observers 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; // [unique.ptr.runtime.modifiers] modifiers pointer release() noexcept; void reset(pointer p = pointer()) noexcept; void reset(nullptr_t) noexcept; template <class U> void reset(U) = delete; void swap(unique_ptr& u) noexcept; // disable copy from lvalue 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.
Conversions between different types of unique_ptr<T[], D> or to or from the non-array forms of unique_ptr produce an ill-formed program.
Pointers to types derived from T are rejected by the constructors, and by reset.
The observers operator* and operator-> are not provided.
The indexing observer operator[] is provided.
The default deleter will call delete[].
Descriptions are provided below only for member functions that have behavior different from the primary template.
The template argument T shall be a complete type.
explicit unique_ptr(pointer p) noexcept;
unique_ptr(pointer p, see below d) noexcept;
unique_ptr(pointer p, see below d) noexcept;
These constructors behave the same as in the primary template except that they do not accept pointer types which are convertible to pointer. [ Note: One implementation technique is to create private templated overloads of these members. — end note ]
T& operator[](size_t i) const;
Requires: i < the number of elements in the array to which the stored pointer points.
Returns: get()[i].
void reset(pointer p = pointer()) noexcept;
void reset(nullptr_t p) noexcept;
Effects: If get() == nullptr there are no effects. Otherwise get_deleter()(get()).
Postcondition: get() == p.
template <class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
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);
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);
Requires: Let CT be common_type<unique_ptr<T1, D1>::pointer, unique_ptr<T2, D2>::pointer>::type. Then the specialization less<CT> shall be 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()).
Remarks: If unique_ptr<T1, D1>::pointer is not implicitly convertible to CT or unique_ptr<T2, D2>::pointer is not implicitly convertible to CT, the program is ill-formed.
template <class T1, class D1, class T2, class D2>
bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: !(y < x).
template <class T1, class D1, class T2, class D2>
bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: y < x.
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 < y).
template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
template <class T, class D>
bool operator==(nullptr_t, const unique_ptr<T, D>& x) noexcept;
Returns: !x.
template <class T, class D>
bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
template <class T, class D>
bool operator!=(nullptr_t, const unique_ptr<T, D>& x) noexcept;
Returns: (bool)x.
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);
Requires: The specialization less<unique_ptr<T, D>::pointer> shall be 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).
namespace std {
class bad_weak_ptr: public std::exception {
public:
bad_weak_ptr() noexcept;
};
} // namespace std
An exception of type bad_weak_ptr is thrown by the shared_ptr constructor taking a weak_ptr.
Postconditions: what() returns "bad_weak_ptr".
The weak_ptr class template stores a weak reference to an object that is already managed by a shared_ptr. To access the object, a weak_ptr can be converted to a shared_ptr using the member function lock.
namespace std { template<class T> class weak_ptr { public: typedef T element_type; // [util.smartptr.weak.const], constructors constexpr weak_ptr() noexcept; template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept; weak_ptr(weak_ptr const& r) noexcept; template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept; // [util.smartptr.weak.dest], destructor ~weak_ptr(); // [util.smartptr.weak.assign], assignment weak_ptr& operator=(weak_ptr const& r) noexcept; template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept; template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept; // [util.smartptr.weak.mod], modifiers void swap(weak_ptr& r) noexcept; void reset() noexcept; // [util.smartptr.weak.obs], observers long use_count() const noexcept; bool expired() const noexcept; shared_ptr<T> lock() const noexcept; template<class U> bool owner_before(shared_ptr<U> const& b); template<class U> bool owner_before(weak_ptr<U> const& b); }; // [util.smartptr.weak.spec], specialized algorithms template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept; } // namespace std
Specializations of weak_ptr shall be CopyConstructible and CopyAssignable, allowing their use in standard containers. The template parameter T of weak_ptr may be an incomplete type.
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;
Requires: The second and third constructors shall not participate in the overload resolution unless Y* is implicitly convertible to 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().
Effects: Destroys this weak_ptr object but has no effect on the object its stored pointer points to.
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.
void swap(weak_ptr& r) noexcept;
Effects: Exchanges the contents of *this and r.
Effects: Equivalent to weak_ptr().swap(*this).
long use_count() const noexcept;
Returns: 0 if *this is empty; otherwise, the number of shared_ptr instances that share ownership with *this.
[ Note: use_count() is not necessarily efficient. — end note ]
bool expired() const noexcept;
Returns: use_count() == 0.
[ Note: expired() may be faster than use_count(). — end note ]
shared_ptr<T> lock() const noexcept;
Returns: expired() ? shared_ptr<T>() : shared_ptr<T>(*this).
template<class U> bool owner_before(shared_ptr<U> const& b);
template<class U> bool owner_before(weak_ptr<U> const& b);
Returns: An unspecified value such that
x.owner_before(y) defines a strict weak ordering as defined in [alg.sorting];
under the equivalence relation defined by owner_before, !a.owner_before(b) && !b.owner_before(a), two shared_ptr or weak_ptr instances are equivalent if and only if they share ownership or are both empty.
template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
Effects: Equivalent to a.swap(b).
The class template owner_less allows ownership-based mixed comparisons of shared and weak pointers.
namespace std { template<class T> struct owner_less; template<class T> struct owner_less<shared_ptr<T> > { typedef bool result_type; typedef shared_ptr<T> first_argument_type; typedef shared_ptr<T> second_argument_type; bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const; bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const; bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const; }; template<class T> struct owner_less<weak_ptr<T> > { typedef bool result_type; typedef weak_ptr<T> first_argument_type; typedef weak_ptr<T> second_argument_type; bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const; bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const; bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const; }; }
operator()(x,y) shall return x.owner_before(y). [ Note: Note that
operator() defines a strict weak ordering as defined in [alg.sorting];
under the equivalence relation defined by operator(), !operator()(a, b) && !operator()(b, a), two shared_ptr or weak_ptr instances are equivalent if and only if they share ownership or are both empty.
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<X> {
};
int main() {
shared_ptr<X> p(new X);
shared_ptr<X> q = p->shared_from_this();
assert(p == q);
assert(!(p < q ) && !(q < p)); // p and q share ownership
}
— end example ]
namespace std {
template<class T> class enable_shared_from_this {
protected:
constexpr enable_shared_from_this() noexcept;
enable_shared_from_this(enable_shared_from_this const&) noexcept;
enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
~enable_shared_from_this();
public:
shared_ptr<T> shared_from_this();
shared_ptr<T const> shared_from_this() const;
};
} // namespace std
The template parameter T of enable_shared_from_this may be an incomplete type.
constexpr enable_shared_from_this() noexcept;
enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
Effects: Constructs an enable_shared_from_this<T> object.
enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
Returns: *this.
Effects: Destroys *this.
shared_ptr<T> shared_from_this();
shared_ptr<T const> shared_from_this() const;
Requires: enable_shared_from_this<T> shall be an accessible base class of T. *this shall be a subobject of an object t of type T. There shall be at least one shared_ptr instance p that owns &t.
Returns: A shared_ptr<T> object r that shares ownership with p.
Postconditions: r.get() == this.
[ Note: A possible implementation is shown below:
template<class T> class enable_shared_from_this { private: weak_ptr<T> __weak_this; protected: constexpr enable_shared_from_this() : __weak_this() { } enable_shared_from_this(enable_shared_from_this const &) { } enable_shared_from_this& operator=(enable_shared_from_this const &) { return *this; } ~enable_shared_from_this() { } public: shared_ptr<T> shared_from_this() { return shared_ptr<T>(__weak_this); } shared_ptr<T const> shared_from_this() const { return shared_ptr<T const>(__weak_this); } };
The shared_ptr constructors that create unique pointers can detect the presence of an enable_shared_from_this base and assign the newly created shared_ptr to its __weak_this member. — end note ]
template <class T, class D> struct hash<unique_ptr<T, D> >;
Requires: The template specialization shall meet the requirements of class template hash ([unord.hash]). For an object p of type UP, where UP is unique_ptr<T, D>, hash<UP>()(p) shall evaluate to the same value as hash<typename UP::pointer>()(p.get()). The specialization hash<typename UP::pointer> shall be well-formed.
template <class T> struct hash<shared_ptr<T> >;
Requires: The template specialization shall meet the requirements of class template hash ([unord.hash]). For an object p of type shared_ptr<T>, hash<shared_ptr<T> >()(p) shall evaluate to the same value as hash<T*>()(p.get()).