[util.smartptr.shared.general]

# 20 Memory management library [[mem]](./#mem)

## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.shared.general)

### 20.3.2 Shared-ownership pointers [[util.sharedptr]](util.sharedptr#util.smartptr.shared.general)

#### 20.3.2.2 Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared#general)

#### 20.3.2.2.1 General [util.smartptr.shared.general]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3487)

The shared_ptr class template stores a pointer, usually obtained
via new[.](#1.sentence-1)

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[.](#1.sentence-2)

Ashared_ptr is said to be empty if it does not own a pointer[.](#1.sentence-3)

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]](util.smartptr.shared.const "20.3.2.2.2 Constructors"), constructorsconstexpr shared_ptr() noexcept; constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }template<class Y>constexpr explicit shared_ptr(Y* p); template<class Y, class D>constexpr shared_ptr(Y* p, D d); template<class Y, class D, class A>constexpr shared_ptr(Y* p, D d, A a); template<class D>constexpr shared_ptr(nullptr_t p, D d); template<class D, class A>constexpr shared_ptr(nullptr_t p, D d, A a); template<class Y>constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept; template<class Y>constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept; constexpr shared_ptr(const shared_ptr& r) noexcept; template<class Y>constexpr shared_ptr(const shared_ptr<Y>& r) noexcept; constexpr shared_ptr(shared_ptr&& r) noexcept; template<class Y>constexpr shared_ptr(shared_ptr<Y>&& r) noexcept; template<class Y>constexpr explicit shared_ptr(const weak_ptr<Y>& r); template<class Y, class D>constexpr shared_ptr(unique_ptr<Y, D>&& r); // [[util.smartptr.shared.dest]](util.smartptr.shared.dest "20.3.2.2.3 Destructor"), destructorconstexpr ~shared_ptr(); // [[util.smartptr.shared.assign]](util.smartptr.shared.assign "20.3.2.2.4 Assignment"), assignmentconstexpr shared_ptr& operator=(const shared_ptr& r) noexcept; template<class Y>constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept; constexpr shared_ptr& operator=(shared_ptr&& r) noexcept; template<class Y>constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept; template<class Y, class D>constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r); // [[util.smartptr.shared.mod]](util.smartptr.shared.mod "20.3.2.2.5 Modifiers"), modifiersconstexpr void swap(shared_ptr& r) noexcept; constexpr void reset() noexcept; template<class Y>constexpr void reset(Y* p); template<class Y, class D>constexpr void reset(Y* p, D d); template<class Y, class D, class A>constexpr void reset(Y* p, D d, A a); // [[util.smartptr.shared.obs]](util.smartptr.shared.obs "20.3.2.2.6 Observers"), observersconstexpr element_type* get() const noexcept; constexpr T& operator*() const noexcept; constexpr T* operator->() const noexcept; constexpr element_type& operator[](ptrdiff_t i) const; constexpr long use_count() const noexcept; constexpr explicit operator bool() const noexcept; template<class U>constexpr bool owner_before(const shared_ptr<U>& b) const noexcept; template<class U>constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
 size_t owner_hash() const noexcept; template<class U>constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept; template<class U>constexpr bool owner_equal(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>;}

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3578)

Specializations of shared_ptr shall be [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"),[*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]"), and [*Cpp17LessThanComparable*](utility.arg.requirements#:Cpp17LessThanComparable "16.4.4.2 Template argument requirements [utility.arg.requirements]"), allowing their use in standard
containers[.](#2.sentence-1)

Specializations of shared_ptr shall be
contextually convertible to bool,
allowing their use in boolean expressions and declarations in conditions[.](#2.sentence-2)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3585)

The template parameter T of shared_ptr may be an incomplete type[.](#3.sentence-1)

[*Note [1](#note-1)*:

T can be a function type[.](#3.sentence-2)

â *end note*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3592)

[*Example [1](#example-1)*: if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {// do something with px} â *end example*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3601)

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[.](#5.sentence-1)

Changes in use_count() do not
reflect modifications that can introduce data races[.](#5.sentence-2)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3607)

For the purposes of [[smartptr]](smartptr "20.3 Smart pointers"),
a pointer type Y* is said to be[*compatible with*](#def:compatible_with,shared_ptr "20.3.2.2.1 General [util.smartptr.shared.general]") a pointer type T* when eitherY* is convertible to T* orY is U[N] and T is cv U[][.](#6.sentence-1)
