20 Memory management library [mem]

20.3 Smart pointers [smartptr]

20.3.2 Shared-ownership pointers [util.sharedptr]

20.3.2.2 Class template shared_ptr [util.smartptr.shared]

20.3.2.2.1 General [util.smartptr.shared.general]

The shared_ptr class template stores a pointer, usually obtained via new.
shared_ptr implements semantics of shared ownership; the last remaining owner of the pointer is responsible for destroying the object, or otherwise releasing the resources associated with the stored pointer.
A shared_ptr is said to be empty if it does not own a pointer.
namespace std { template<class T> class shared_ptr { public: using element_type = remove_extent_t<T>; using weak_type = weak_ptr<T>; // [util.smartptr.shared.const], constructors constexpr shared_ptr() noexcept; constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } template<class Y> explicit shared_ptr(Y* p); template<class Y, class D> shared_ptr(Y* p, D d); template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); template<class D> shared_ptr(nullptr_t p, D d); template<class D, class A> shared_ptr(nullptr_t p, D d, A a); template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept; template<class Y> shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept; shared_ptr(const shared_ptr& r) noexcept; template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept; shared_ptr(shared_ptr&& r) noexcept; template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept; template<class Y> explicit shared_ptr(const weak_ptr<Y>& r); template<class Y, class D> shared_ptr(unique_ptr<Y, D>&& r); // [util.smartptr.shared.dest], destructor ~shared_ptr(); // [util.smartptr.shared.assign], assignment shared_ptr& operator=(const shared_ptr& r) noexcept; template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept; shared_ptr& operator=(shared_ptr&& r) noexcept; template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept; template<class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r); // [util.smartptr.shared.mod], modifiers void swap(shared_ptr& r) noexcept; void reset() noexcept; template<class Y> void reset(Y* p); template<class Y, class D> void reset(Y* p, D d); template<class Y, class D, class A> void reset(Y* p, D d, A a); // [util.smartptr.shared.obs], observers element_type* get() const noexcept; T& operator*() const noexcept; T* operator->() const noexcept; element_type& operator[](ptrdiff_t i) const; long use_count() const noexcept; explicit operator bool() 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<class T> shared_ptr(weak_ptr<T>) -> shared_ptr<T>; template<class T, class D> shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>; }
Specializations of shared_ptr shall be Cpp17CopyConstructible, Cpp17CopyAssignable, and Cpp17LessThanComparable, allowing their use in standard containers.
Specializations of shared_ptr shall be contextually convertible to bool, allowing their use in boolean expressions and declarations in conditions.
The template parameter T of shared_ptr may be an incomplete type.
[Note 1: 
T can be a function type.
— end note]
[Example 1: if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) { // do something with px } — end example]
For purposes of determining the presence of a data race, member functions shall access and modify only the shared_ptr and weak_ptr objects themselves and not objects they refer to.
Changes in use_count() do not reflect modifications that can introduce data races.
For the purposes of subclause [smartptr], a pointer type Y* is said to be compatible with a pointer type T* when either Y* is convertible to T* or Y is U[N] and T is cv U[].