[util.smartptr.shared.const]

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

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

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

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

#### 20.3.2.2.2 Constructors [util.smartptr.shared.const]

[1](#1)

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

In the constructor definitions below,
enables shared_from_this with p,
for a pointer p of type Y*,
means that if Y has an unambiguous and accessible base class
that is a specialization of enable_shared_from_this ([[util.smartptr.enab]](util.smartptr.enab "20.3.2.7 Class template enable_­shared_­from_­this")),
then remove_cv_t<Y>* shall be implicitly convertible to T* and
the constructor evaluates the statement:if (p != nullptr && p->*weak-this*.expired()) p->*weak-this* = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));

The assignment to the *weak-this* member is not atomic and
conflicts with any potentially concurrent access to the same object ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#1.sentence-2)

[ð](#lib:shared_ptr,constructor)

`constexpr shared_ptr() noexcept;
`

[2](#2)

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

*Postconditions*: use_count() == 0 && get() == nullptr[.](#2.sentence-1)

[ð](#lib:shared_ptr,constructor_)

`template<class Y> constexpr explicit shared_ptr(Y* p);
`

[3](#3)

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

*Constraints*: When T is an array type,
the expression delete[] p is well-formed and eitherT is U[N] and Y(*)[N] is convertible to T*, orT is U[] and Y(*)[] is convertible to T*[.](#3.sentence-1)

When T is not an array type,
the expression delete p is well-formed andY* is convertible to T*[.](#3.sentence-2)

[4](#4)

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

*Mandates*: Y is a complete type[.](#4.sentence-1)

[5](#5)

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

*Preconditions*: The expressiondelete[] p, when T is an array type, ordelete p, when T is not an array type,
has well-defined behavior, and
does not throw exceptions[.](#5.sentence-1)

[6](#6)

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

*Effects*: When T is not an array type,
constructs a shared_ptr object
that owns the pointer p[.](#6.sentence-1)

Otherwise, constructs a shared_ptr that owns p and a deleter of an
unspecified type that calls delete[] p[.](#6.sentence-2)

When T is not an array type,
enables shared_from_this with p[.](#6.sentence-3)

If an exception is thrown, delete p is called
when T is not an array type, delete[] p otherwise[.](#6.sentence-4)

[7](#7)

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

*Postconditions*: use_count() == 1 && get() == p[.](#7.sentence-1)

[8](#8)

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

*Throws*: bad_alloc, or an implementation-defined exception when a resource other than memory cannot be obtained[.](#8.sentence-1)

[ð](#lib:shared_ptr,constructor__)

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

[9](#9)

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

*Constraints*: is_move_constructible_v<D> is true, andd(p) is a well-formed expression[.](#9.sentence-1)

For the first two overloads:

- [(9.1)](#9.1)

  If T is an array type, then eitherT is U[N] and Y(*)[N] is convertible to T*, orT is U[] and Y(*)[] is convertible to T*[.](#9.1.sentence-1)

- [(9.2)](#9.2)

  If T is not an array type, then Y* is convertible to T*[.](#9.2.sentence-1)

[10](#10)

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

*Preconditions*: Construction of d and a deleter of type D initialized with std​::​move(d) do not throw exceptions[.](#10.sentence-1)

The expression d(p) has well-defined behavior and does not throw exceptions[.](#10.sentence-2)

A meets
the [*Cpp17Allocator*](allocator.requirements.general#:Cpp17Allocator "16.4.4.6.1 General [allocator.requirements.general]") requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))[.](#10.sentence-3)

[11](#11)

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

*Effects*: Constructs a shared_ptr object that owns the
object p and the deleter d[.](#11.sentence-1)

When T is not an array type,
the first and second constructors enable shared_from_this with p[.](#11.sentence-2)

The second and fourth constructors shall use a copy of a to
allocate memory for internal use[.](#11.sentence-3)

If an exception is thrown, d(p) is called[.](#11.sentence-4)

[12](#12)

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

*Postconditions*: use_count() == 1 && get() == p[.](#12.sentence-1)

[13](#13)

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

*Throws*: bad_alloc, or an implementation-defined exception
when a resource other than memory cannot be obtained[.](#13.sentence-1)

[ð](#lib:shared_ptr,constructor___)

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

[14](#14)

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

*Effects*: Constructs a shared_ptr instance that
stores p and shares ownership with
the initial value of r[.](#14.sentence-1)

[15](#15)

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

*Postconditions*: get() == p[.](#15.sentence-1)

For the second overload,r is empty and r.get() == nullptr[.](#15.sentence-2)

[16](#16)

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

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

Use of this constructor leads to a dangling pointer
unless p remains valid
at least until the ownership group of r is destroyed[.](#16.sentence-1)

â *end note*]

[17](#17)

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

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

This constructor allows creation of an emptyshared_ptr instance with a non-null stored pointer[.](#17.sentence-1)

â *end note*]

[ð](#lib:shared_ptr,constructor____)

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

[18](#18)

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

*Constraints*: For the second constructor, Y* is compatible with T*[.](#18.sentence-1)

[19](#19)

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

*Effects*: If r is empty, constructs
an empty shared_ptr object; otherwise, constructs
a shared_ptr object that shares ownership with r[.](#19.sentence-1)

[20](#20)

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

*Postconditions*: get() == r.get() && use_count() == r.use_count()[.](#20.sentence-1)

[ð](#lib:shared_ptr,constructor_____)

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

[21](#21)

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

*Constraints*: For the second constructor, Y* is compatible with T*[.](#21.sentence-1)

[22](#22)

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

*Effects*: Move constructs a shared_ptr instance from r[.](#22.sentence-1)

[23](#23)

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

*Postconditions*: *this contains the old value ofr[.](#23.sentence-1)

r is empty, and r.get() == nullptr[.](#23.sentence-2)

[ð](#lib:shared_ptr,constructor______)

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

[24](#24)

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

*Constraints*: Y* is compatible with T*[.](#24.sentence-1)

[25](#25)

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

*Effects*: Constructs a shared_ptr object that shares ownership withr and stores a copy of the pointer stored in r[.](#25.sentence-1)

If an exception is thrown, the constructor has no effect[.](#25.sentence-2)

[26](#26)

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

*Postconditions*: use_count() == r.use_count()[.](#26.sentence-1)

[27](#27)

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

*Throws*: bad_weak_ptr when r.expired()[.](#27.sentence-1)

[ð](#lib:shared_ptr,constructor_______)

`template<class Y, class D> constexpr shared_ptr(unique_ptr<Y, D>&& r);
`

[28](#28)

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

*Constraints*: Y* is compatible with T* andunique_ptr<Y, D>​::​pointer is convertible to element_type*[.](#28.sentence-1)

[29](#29)

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

*Effects*: If r.get() == nullptr, equivalent to shared_ptr()[.](#29.sentence-1)

Otherwise, if D is not a reference type,
equivalent to shared_ptr(r.release(), std​::​move(r.get_deleter()))[.](#29.sentence-2)

Otherwise, equivalent to shared_ptr(r.release(), ref(r.get_deleter()))[.](#29.sentence-3)

If an exception is thrown, the constructor has no effect[.](#29.sentence-4)
