1920 lines
81 KiB
Markdown
1920 lines
81 KiB
Markdown
[util.sharedptr]
|
||
|
||
# 20 Memory management library [[mem]](./#mem)
|
||
|
||
## 20.3 Smart pointers [[smartptr]](smartptr#util.sharedptr)
|
||
|
||
### 20.3.2 Shared-ownership pointers [util.sharedptr]
|
||
|
||
#### [20.3.2.1](#util.smartptr.weak.bad) Class bad_weak_ptr [[util.smartptr.weak.bad]](util.smartptr.weak.bad)
|
||
|
||
[ð](#lib:bad_weak_ptr)
|
||
|
||
namespace std {class bad_weak_ptr : public exception {public:// see [[exception]](exception "17.9.3 Class exception") for the specification of the special member functionsconstexpr const char* what() const noexcept override; };}
|
||
|
||
[1](#util.smartptr.weak.bad-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3468)
|
||
|
||
An exception of type bad_weak_ptr is thrown by the shared_ptr constructor taking a weak_ptr[.](#util.smartptr.weak.bad-1.sentence-1)
|
||
|
||
[ð](#lib:what,bad_weak_ptr)
|
||
|
||
`constexpr const char* what() const noexcept override;
|
||
`
|
||
|
||
[2](#util.smartptr.weak.bad-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3478)
|
||
|
||
*Returns*: An implementation-defined ntbs[.](#util.smartptr.weak.bad-2.sentence-1)
|
||
|
||
#### [20.3.2.2](#util.smartptr.shared) Class template shared_ptr [[util.smartptr.shared]](util.smartptr.shared)
|
||
|
||
#### [20.3.2.2.1](#util.smartptr.shared.general) General [[util.smartptr.shared.general]](util.smartptr.shared.general)
|
||
|
||
[1](#util.smartptr.shared.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3487)
|
||
|
||
The shared_ptr class template stores a pointer, usually obtained
|
||
via new[.](#util.smartptr.shared.general-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[.](#util.smartptr.shared.general-1.sentence-2)
|
||
|
||
Ashared_ptr is said to be empty if it does not own a pointer[.](#util.smartptr.shared.general-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](#util.smartptr.shared.general-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[.](#util.smartptr.shared.general-2.sentence-1)
|
||
|
||
Specializations of shared_ptr shall be
|
||
contextually convertible to bool,
|
||
allowing their use in boolean expressions and declarations in conditions[.](#util.smartptr.shared.general-2.sentence-2)
|
||
|
||
[3](#util.smartptr.shared.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3585)
|
||
|
||
The template parameter T of shared_ptr may be an incomplete type[.](#util.smartptr.shared.general-3.sentence-1)
|
||
|
||
[*Note [1](#util.smartptr.shared.general-note-1)*:
|
||
|
||
T can be a function type[.](#util.smartptr.shared.general-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#util.smartptr.shared.general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3592)
|
||
|
||
[*Example [1](#util.smartptr.shared.general-example-1)*: if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {// do something with px} â *end example*]
|
||
|
||
[5](#util.smartptr.shared.general-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[.](#util.smartptr.shared.general-5.sentence-1)
|
||
|
||
Changes in use_count() do not
|
||
reflect modifications that can introduce data races[.](#util.smartptr.shared.general-5.sentence-2)
|
||
|
||
[6](#util.smartptr.shared.general-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[][.](#util.smartptr.shared.general-6.sentence-1)
|
||
|
||
#### [20.3.2.2.2](#util.smartptr.shared.const) Constructors [[util.smartptr.shared.const]](util.smartptr.shared.const)
|
||
|
||
[1](#util.smartptr.shared.const-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"))[.](#util.smartptr.shared.const-1.sentence-2)
|
||
|
||
[ð](#lib:shared_ptr,constructor)
|
||
|
||
`constexpr shared_ptr() noexcept;
|
||
`
|
||
|
||
[2](#util.smartptr.shared.const-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3638)
|
||
|
||
*Postconditions*: use_count() == 0 && get() == nullptr[.](#util.smartptr.shared.const-2.sentence-1)
|
||
|
||
[ð](#lib:shared_ptr,constructor_)
|
||
|
||
`template<class Y> constexpr explicit shared_ptr(Y* p);
|
||
`
|
||
|
||
[3](#util.smartptr.shared.const-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*[.](#util.smartptr.shared.const-3.sentence-1)
|
||
|
||
When T is not an array type,
|
||
the expression delete p is well-formed andY* is convertible to T*[.](#util.smartptr.shared.const-3.sentence-2)
|
||
|
||
[4](#util.smartptr.shared.const-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3659)
|
||
|
||
*Mandates*: Y is a complete type[.](#util.smartptr.shared.const-4.sentence-1)
|
||
|
||
[5](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-5.sentence-1)
|
||
|
||
[6](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-6.sentence-1)
|
||
|
||
Otherwise, constructs a shared_ptr that owns p and a deleter of an
|
||
unspecified type that calls delete[] p[.](#util.smartptr.shared.const-6.sentence-2)
|
||
|
||
When T is not an array type,
|
||
enables shared_from_this with p[.](#util.smartptr.shared.const-6.sentence-3)
|
||
|
||
If an exception is thrown, delete p is called
|
||
when T is not an array type, delete[] p otherwise[.](#util.smartptr.shared.const-6.sentence-4)
|
||
|
||
[7](#util.smartptr.shared.const-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3684)
|
||
|
||
*Postconditions*: use_count() == 1 && get() == p[.](#util.smartptr.shared.const-7.sentence-1)
|
||
|
||
[8](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-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](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-9.sentence-1)
|
||
|
||
For the first two overloads:
|
||
|
||
- [(9.1)](#util.smartptr.shared.const-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*[.](#util.smartptr.shared.const-9.1.sentence-1)
|
||
|
||
- [(9.2)](#util.smartptr.shared.const-9.2)
|
||
|
||
If T is not an array type, then Y* is convertible to T*[.](#util.smartptr.shared.const-9.2.sentence-1)
|
||
|
||
[10](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-10.sentence-1)
|
||
|
||
The expression d(p) has well-defined behavior and does not throw exceptions[.](#util.smartptr.shared.const-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"))[.](#util.smartptr.shared.const-10.sentence-3)
|
||
|
||
[11](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-11.sentence-1)
|
||
|
||
When T is not an array type,
|
||
the first and second constructors enable shared_from_this with p[.](#util.smartptr.shared.const-11.sentence-2)
|
||
|
||
The second and fourth constructors shall use a copy of a to
|
||
allocate memory for internal use[.](#util.smartptr.shared.const-11.sentence-3)
|
||
|
||
If an exception is thrown, d(p) is called[.](#util.smartptr.shared.const-11.sentence-4)
|
||
|
||
[12](#util.smartptr.shared.const-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3737)
|
||
|
||
*Postconditions*: use_count() == 1 && get() == p[.](#util.smartptr.shared.const-12.sentence-1)
|
||
|
||
[13](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-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](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-14.sentence-1)
|
||
|
||
[15](#util.smartptr.shared.const-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3761)
|
||
|
||
*Postconditions*: get() == p[.](#util.smartptr.shared.const-15.sentence-1)
|
||
|
||
For the second overload,r is empty and r.get() == nullptr[.](#util.smartptr.shared.const-15.sentence-2)
|
||
|
||
[16](#util.smartptr.shared.const-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3767)
|
||
|
||
[*Note [1](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-16.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[17](#util.smartptr.shared.const-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3774)
|
||
|
||
[*Note [2](#util.smartptr.shared.const-note-2)*:
|
||
|
||
This constructor allows creation of an emptyshared_ptr instance with a non-null stored pointer[.](#util.smartptr.shared.const-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](#util.smartptr.shared.const-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3788)
|
||
|
||
*Constraints*: For the second constructor, Y* is compatible with T*[.](#util.smartptr.shared.const-18.sentence-1)
|
||
|
||
[19](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-19.sentence-1)
|
||
|
||
[20](#util.smartptr.shared.const-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3798)
|
||
|
||
*Postconditions*: get() == r.get() && use_count() == r.use_count()[.](#util.smartptr.shared.const-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](#util.smartptr.shared.const-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3810)
|
||
|
||
*Constraints*: For the second constructor, Y* is compatible with T*[.](#util.smartptr.shared.const-21.sentence-1)
|
||
|
||
[22](#util.smartptr.shared.const-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3814)
|
||
|
||
*Effects*: Move constructs a shared_ptr instance from r[.](#util.smartptr.shared.const-22.sentence-1)
|
||
|
||
[23](#util.smartptr.shared.const-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3818)
|
||
|
||
*Postconditions*: *this contains the old value ofr[.](#util.smartptr.shared.const-23.sentence-1)
|
||
|
||
r is empty, and r.get() == nullptr[.](#util.smartptr.shared.const-23.sentence-2)
|
||
|
||
[ð](#lib:shared_ptr,constructor______)
|
||
|
||
`template<class Y> constexpr explicit shared_ptr(const weak_ptr<Y>& r);
|
||
`
|
||
|
||
[24](#util.smartptr.shared.const-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3831)
|
||
|
||
*Constraints*: Y* is compatible with T*[.](#util.smartptr.shared.const-24.sentence-1)
|
||
|
||
[25](#util.smartptr.shared.const-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[.](#util.smartptr.shared.const-25.sentence-1)
|
||
|
||
If an exception is thrown, the constructor has no effect[.](#util.smartptr.shared.const-25.sentence-2)
|
||
|
||
[26](#util.smartptr.shared.const-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3841)
|
||
|
||
*Postconditions*: use_count() == r.use_count()[.](#util.smartptr.shared.const-26.sentence-1)
|
||
|
||
[27](#util.smartptr.shared.const-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3845)
|
||
|
||
*Throws*: bad_weak_ptr when r.expired()[.](#util.smartptr.shared.const-27.sentence-1)
|
||
|
||
[ð](#lib:shared_ptr,constructor_______)
|
||
|
||
`template<class Y, class D> constexpr shared_ptr(unique_ptr<Y, D>&& r);
|
||
`
|
||
|
||
[28](#util.smartptr.shared.const-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*[.](#util.smartptr.shared.const-28.sentence-1)
|
||
|
||
[29](#util.smartptr.shared.const-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3862)
|
||
|
||
*Effects*: If r.get() == nullptr, equivalent to shared_ptr()[.](#util.smartptr.shared.const-29.sentence-1)
|
||
|
||
Otherwise, if D is not a reference type,
|
||
equivalent to shared_ptr(r.release(), std::move(r.get_deleter()))[.](#util.smartptr.shared.const-29.sentence-2)
|
||
|
||
Otherwise, equivalent to shared_ptr(r.release(), ref(r.get_deleter()))[.](#util.smartptr.shared.const-29.sentence-3)
|
||
|
||
If an exception is thrown, the constructor has no effect[.](#util.smartptr.shared.const-29.sentence-4)
|
||
|
||
#### [20.3.2.2.3](#util.smartptr.shared.dest) Destructor [[util.smartptr.shared.dest]](util.smartptr.shared.dest)
|
||
|
||
[ð](#lib:shared_ptr,destructor)
|
||
|
||
`constexpr ~shared_ptr();
|
||
`
|
||
|
||
[1](#util.smartptr.shared.dest-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3879)
|
||
|
||
*Effects*:
|
||
|
||
- [(1.1)](#util.smartptr.shared.dest-1.1)
|
||
|
||
If *this is empty or shares ownership with anothershared_ptr instance (use_count() > 1), there are no side effects[.](#util.smartptr.shared.dest-1.1.sentence-1)
|
||
|
||
- [(1.2)](#util.smartptr.shared.dest-1.2)
|
||
|
||
Otherwise, if *this owns an objectp and a deleter d, d(p) is called[.](#util.smartptr.shared.dest-1.2.sentence-1)
|
||
|
||
- [(1.3)](#util.smartptr.shared.dest-1.3)
|
||
|
||
Otherwise, *this owns a pointer p,
|
||
and delete p is called[.](#util.smartptr.shared.dest-1.3.sentence-1)
|
||
|
||
[2](#util.smartptr.shared.dest-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3894)
|
||
|
||
[*Note [1](#util.smartptr.shared.dest-note-1)*:
|
||
|
||
Since the destruction of *this decreases the number of instances that share ownership with *this by one,
|
||
after *this has been destroyed
|
||
all shared_ptr instances that shared ownership with*this will report a use_count() that is one less
|
||
than its previous value[.](#util.smartptr.shared.dest-2.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.2.2.4](#util.smartptr.shared.assign) Assignment [[util.smartptr.shared.assign]](util.smartptr.shared.assign)
|
||
|
||
[ð](#lib:operator=,shared_ptr)
|
||
|
||
`constexpr shared_ptr& operator=(const shared_ptr& r) noexcept;
|
||
template<class Y> constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.shared.assign-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3914)
|
||
|
||
*Effects*: Equivalent to shared_ptr(r).swap(*this)[.](#util.smartptr.shared.assign-1.sentence-1)
|
||
|
||
[2](#util.smartptr.shared.assign-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3918)
|
||
|
||
*Returns*: *this[.](#util.smartptr.shared.assign-2.sentence-1)
|
||
|
||
[3](#util.smartptr.shared.assign-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3922)
|
||
|
||
[*Note [1](#util.smartptr.shared.assign-note-1)*:
|
||
|
||
The use count updates caused by the temporary object
|
||
construction and destruction are not observable side
|
||
effects, so the implementation can meet the effects (and the
|
||
implied guarantees) via different means, without creating a
|
||
temporary[.](#util.smartptr.shared.assign-3.sentence-1)
|
||
|
||
In particular, in the example:shared_ptr<int> p(new int);
|
||
shared_ptr<void> q(p);
|
||
p = p;
|
||
q = p; both assignments can be no-ops[.](#util.smartptr.shared.assign-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:operator=,shared_ptr_)
|
||
|
||
`constexpr shared_ptr& operator=(shared_ptr&& r) noexcept;
|
||
template<class Y> constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
|
||
`
|
||
|
||
[4](#util.smartptr.shared.assign-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3946)
|
||
|
||
*Effects*: Equivalent to shared_ptr(std::move(r)).swap(*this)[.](#util.smartptr.shared.assign-4.sentence-1)
|
||
|
||
[5](#util.smartptr.shared.assign-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3950)
|
||
|
||
*Returns*: *this[.](#util.smartptr.shared.assign-5.sentence-1)
|
||
|
||
[ð](#lib:operator=,shared_ptr__)
|
||
|
||
`template<class Y, class D> constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r);
|
||
`
|
||
|
||
[6](#util.smartptr.shared.assign-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3961)
|
||
|
||
*Effects*: Equivalent to shared_ptr(std::move(r)).swap(*this)[.](#util.smartptr.shared.assign-6.sentence-1)
|
||
|
||
[7](#util.smartptr.shared.assign-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3965)
|
||
|
||
*Returns*: *this[.](#util.smartptr.shared.assign-7.sentence-1)
|
||
|
||
#### [20.3.2.2.5](#util.smartptr.shared.mod) Modifiers [[util.smartptr.shared.mod]](util.smartptr.shared.mod)
|
||
|
||
[ð](#lib:swap,shared_ptr)
|
||
|
||
`constexpr void swap(shared_ptr& r) noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.shared.mod-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3979)
|
||
|
||
*Effects*: Exchanges the contents of *this and r[.](#util.smartptr.shared.mod-1.sentence-1)
|
||
|
||
[ð](#lib:reset,shared_ptr)
|
||
|
||
`constexpr void reset() noexcept;
|
||
`
|
||
|
||
[2](#util.smartptr.shared.mod-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3990)
|
||
|
||
*Effects*: Equivalent to shared_ptr().swap(*this)[.](#util.smartptr.shared.mod-2.sentence-1)
|
||
|
||
[ð](#lib:reset,shared_ptr_)
|
||
|
||
`template<class Y> constexpr void reset(Y* p);
|
||
`
|
||
|
||
[3](#util.smartptr.shared.mod-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4001)
|
||
|
||
*Effects*: Equivalent to shared_ptr(p).swap(*this)[.](#util.smartptr.shared.mod-3.sentence-1)
|
||
|
||
[ð](#lib:reset,shared_ptr__)
|
||
|
||
`template<class Y, class D> constexpr void reset(Y* p, D d);
|
||
`
|
||
|
||
[4](#util.smartptr.shared.mod-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4012)
|
||
|
||
*Effects*: Equivalent to shared_ptr(p, d).swap(*this)[.](#util.smartptr.shared.mod-4.sentence-1)
|
||
|
||
[ð](#lib:reset,shared_ptr___)
|
||
|
||
`template<class Y, class D, class A> constexpr void reset(Y* p, D d, A a);
|
||
`
|
||
|
||
[5](#util.smartptr.shared.mod-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4023)
|
||
|
||
*Effects*: Equivalent to shared_ptr(p, d, a).swap(*this)[.](#util.smartptr.shared.mod-5.sentence-1)
|
||
|
||
#### [20.3.2.2.6](#util.smartptr.shared.obs) Observers [[util.smartptr.shared.obs]](util.smartptr.shared.obs)
|
||
|
||
[ð](#lib:get,shared_ptr)
|
||
|
||
`constexpr element_type* get() const noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.shared.obs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4035)
|
||
|
||
*Returns*: The stored pointer[.](#util.smartptr.shared.obs-1.sentence-1)
|
||
|
||
[ð](#lib:operator*,shared_ptr)
|
||
|
||
`constexpr T& operator*() const noexcept;
|
||
`
|
||
|
||
[2](#util.smartptr.shared.obs-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4046)
|
||
|
||
*Preconditions*: get() != nullptr[.](#util.smartptr.shared.obs-2.sentence-1)
|
||
|
||
[3](#util.smartptr.shared.obs-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4050)
|
||
|
||
*Returns*: *get()[.](#util.smartptr.shared.obs-3.sentence-1)
|
||
|
||
[4](#util.smartptr.shared.obs-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4054)
|
||
|
||
*Remarks*: When T is an array type or cv void,
|
||
it is unspecified whether this
|
||
member function is declared[.](#util.smartptr.shared.obs-4.sentence-1)
|
||
|
||
If it is declared, it is unspecified what its
|
||
return type is, except that the declaration (although not necessarily the
|
||
definition) of the function shall be well-formed[.](#util.smartptr.shared.obs-4.sentence-2)
|
||
|
||
[ð](#lib:operator-%3e,shared_ptr)
|
||
|
||
`constexpr T* operator->() const noexcept;
|
||
`
|
||
|
||
[5](#util.smartptr.shared.obs-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4069)
|
||
|
||
*Preconditions*: get() != nullptr[.](#util.smartptr.shared.obs-5.sentence-1)
|
||
|
||
[6](#util.smartptr.shared.obs-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4073)
|
||
|
||
*Returns*: get()[.](#util.smartptr.shared.obs-6.sentence-1)
|
||
|
||
[7](#util.smartptr.shared.obs-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4077)
|
||
|
||
*Remarks*: When T is an array type,
|
||
it is unspecified whether this member function is declared[.](#util.smartptr.shared.obs-7.sentence-1)
|
||
|
||
If it is declared, it is unspecified what its return type is,
|
||
except that the declaration (although not necessarily the definition)
|
||
of the function shall be well-formed[.](#util.smartptr.shared.obs-7.sentence-2)
|
||
|
||
[ð](#lib:operator%5b%5d,shared_ptr)
|
||
|
||
`constexpr element_type& operator[](ptrdiff_t i) const;
|
||
`
|
||
|
||
[8](#util.smartptr.shared.obs-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4092)
|
||
|
||
*Preconditions*: get() != nullptr is true[.](#util.smartptr.shared.obs-8.sentence-1)
|
||
|
||
[9](#util.smartptr.shared.obs-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4096)
|
||
|
||
*Hardened preconditions*: i ⥠0[.](#util.smartptr.shared.obs-9.sentence-1)
|
||
|
||
If T is U[N], i < N[.](#util.smartptr.shared.obs-9.sentence-2)
|
||
|
||
[10](#util.smartptr.shared.obs-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4100)
|
||
|
||
*Returns*: get()[i][.](#util.smartptr.shared.obs-10.sentence-1)
|
||
|
||
[11](#util.smartptr.shared.obs-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4104)
|
||
|
||
*Throws*: Nothing[.](#util.smartptr.shared.obs-11.sentence-1)
|
||
|
||
[12](#util.smartptr.shared.obs-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4108)
|
||
|
||
*Remarks*: When T is not an array type,
|
||
it is unspecified whether this member function is declared[.](#util.smartptr.shared.obs-12.sentence-1)
|
||
|
||
If it is declared, it is unspecified what its return type is,
|
||
except that the declaration (although not necessarily the definition)
|
||
of the function shall be well-formed[.](#util.smartptr.shared.obs-12.sentence-2)
|
||
|
||
[ð](#lib:use_count,shared_ptr)
|
||
|
||
`constexpr long use_count() const noexcept;
|
||
`
|
||
|
||
[13](#util.smartptr.shared.obs-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4123)
|
||
|
||
*Synchronization*: None[.](#util.smartptr.shared.obs-13.sentence-1)
|
||
|
||
[14](#util.smartptr.shared.obs-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4127)
|
||
|
||
*Returns*: The number of shared_ptr objects, *this included,
|
||
that share ownership with *this, or 0 when *this is
|
||
empty[.](#util.smartptr.shared.obs-14.sentence-1)
|
||
|
||
[15](#util.smartptr.shared.obs-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4133)
|
||
|
||
[*Note [1](#util.smartptr.shared.obs-note-1)*:
|
||
|
||
get() == nullptr does not imply a specific return value of use_count()[.](#util.smartptr.shared.obs-15.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[16](#util.smartptr.shared.obs-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4139)
|
||
|
||
[*Note [2](#util.smartptr.shared.obs-note-2)*:
|
||
|
||
weak_ptr<T>::lock() can affect the return value of use_count()[.](#util.smartptr.shared.obs-16.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[17](#util.smartptr.shared.obs-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4145)
|
||
|
||
[*Note [3](#util.smartptr.shared.obs-note-3)*:
|
||
|
||
When multiple threads
|
||
might affect the return value of use_count(),
|
||
the result is approximate[.](#util.smartptr.shared.obs-17.sentence-1)
|
||
|
||
In particular, use_count() == 1 does not imply that accesses through
|
||
a previously destroyed shared_ptr have in any sense completed[.](#util.smartptr.shared.obs-17.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:operator_bool,shared_ptr)
|
||
|
||
`constexpr explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[18](#util.smartptr.shared.obs-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4161)
|
||
|
||
*Returns*: get() != nullptr[.](#util.smartptr.shared.obs-18.sentence-1)
|
||
|
||
[ð](#lib:owner_before,shared_ptr)
|
||
|
||
`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;
|
||
`
|
||
|
||
[19](#util.smartptr.shared.obs-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4173)
|
||
|
||
*Returns*: An unspecified value such that
|
||
|
||
- [(19.1)](#util.smartptr.shared.obs-19.1)
|
||
|
||
owner_before(b) defines a strict weak ordering as defined in [[alg.sorting]](alg.sorting "26.8 Sorting and related operations");
|
||
|
||
- [(19.2)](#util.smartptr.shared.obs-19.2)
|
||
|
||
!owner_before(b) && !b.owner_before(*this) is true if and only if owner_equal(b) is true[.](#util.smartptr.shared.obs-19.sentence-1)
|
||
|
||
[ð](#lib:owner_hash,shared_ptr)
|
||
|
||
`size_t owner_hash() const noexcept;
|
||
`
|
||
|
||
[20](#util.smartptr.shared.obs-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4191)
|
||
|
||
*Returns*: An unspecified value such that,
|
||
for any object x where owner_equal(x) is true,owner_hash() == x.owner_hash() is true[.](#util.smartptr.shared.obs-20.sentence-1)
|
||
|
||
[ð](#lib:owner_equal,shared_ptr)
|
||
|
||
`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;
|
||
`
|
||
|
||
[21](#util.smartptr.shared.obs-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4207)
|
||
|
||
*Returns*: true if and only if*this and b share ownership or are both empty[.](#util.smartptr.shared.obs-21.sentence-1)
|
||
|
||
Otherwise returns false[.](#util.smartptr.shared.obs-21.sentence-2)
|
||
|
||
[22](#util.smartptr.shared.obs-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4213)
|
||
|
||
*Remarks*: owner_equal is an equivalence relation[.](#util.smartptr.shared.obs-22.sentence-1)
|
||
|
||
#### [20.3.2.2.7](#util.smartptr.shared.create) Creation [[util.smartptr.shared.create]](util.smartptr.shared.create)
|
||
|
||
[1](#util.smartptr.shared.create-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4220)
|
||
|
||
The common requirements that apply to allmake_shared,allocate_shared,make_shared_for_overwrite, andallocate_shared_for_overwrite overloads,
|
||
unless specified otherwise, are described below[.](#util.smartptr.shared.create-1.sentence-1)
|
||
|
||
[ð](#lib:make_shared)
|
||
|
||
`template<class T, ...>
|
||
constexpr shared_ptr<T> make_shared(args);
|
||
template<class T, class A, ...>
|
||
constexpr shared_ptr<T> allocate_shared(const A& a, args);
|
||
template<class T, ...>
|
||
constexpr shared_ptr<T> make_shared_for_overwrite(args);
|
||
template<class T, class A, ...>
|
||
constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
|
||
`
|
||
|
||
[2](#util.smartptr.shared.create-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4242)
|
||
|
||
*Preconditions*: 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"))[.](#util.smartptr.shared.create-2.sentence-1)
|
||
|
||
[3](#util.smartptr.shared.create-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4247)
|
||
|
||
*Effects*: Allocates memory for an object of type T (or U[N] when T is U[],
|
||
where N is determined from *args* as specified by the concrete overload)[.](#util.smartptr.shared.create-3.sentence-1)
|
||
|
||
The object is initialized from *args* as specified by the concrete overload[.](#util.smartptr.shared.create-3.sentence-2)
|
||
|
||
The allocate_shared and allocate_shared_for_overwrite templates
|
||
use a copy of a (rebound for an unspecified value_type) to allocate memory[.](#util.smartptr.shared.create-3.sentence-3)
|
||
|
||
If an exception is thrown, the functions have no effect[.](#util.smartptr.shared.create-3.sentence-4)
|
||
|
||
[4](#util.smartptr.shared.create-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4258)
|
||
|
||
*Postconditions*: r.get() != nullptr && r.use_count() == 1,
|
||
where r is the return value[.](#util.smartptr.shared.create-4.sentence-1)
|
||
|
||
[5](#util.smartptr.shared.create-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4263)
|
||
|
||
*Returns*: A shared_ptr instance that stores and owns the address of
|
||
the newly constructed object[.](#util.smartptr.shared.create-5.sentence-1)
|
||
|
||
[6](#util.smartptr.shared.create-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4268)
|
||
|
||
*Throws*: bad_alloc, or
|
||
an exception thrown from allocate or from the initialization of the object[.](#util.smartptr.shared.create-6.sentence-1)
|
||
|
||
[7](#util.smartptr.shared.create-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4273)
|
||
|
||
*Remarks*:
|
||
|
||
- [(7.1)](#util.smartptr.shared.create-7.1)
|
||
|
||
Implementations should perform no more than one memory allocation[.](#util.smartptr.shared.create-7.1.sentence-1)
|
||
[*Note [1](#util.smartptr.shared.create-note-1)*:
|
||
This provides efficiency equivalent to an intrusive smart pointer[.](#util.smartptr.shared.create-7.1.sentence-2)
|
||
â *end note*]
|
||
|
||
- [(7.2)](#util.smartptr.shared.create-7.2)
|
||
|
||
When an object of an array type U is specified to have
|
||
an initial value of u (of the same type),
|
||
this shall be interpreted to mean that
|
||
each array element of the object has as its initial value
|
||
the corresponding element from u[.](#util.smartptr.shared.create-7.2.sentence-1)
|
||
|
||
- [(7.3)](#util.smartptr.shared.create-7.3)
|
||
|
||
When an object of an array type is specified to have
|
||
a default initial value,
|
||
this shall be interpreted to mean that each array element of the object
|
||
has a default initial value[.](#util.smartptr.shared.create-7.3.sentence-1)
|
||
|
||
- [(7.4)](#util.smartptr.shared.create-7.4)
|
||
|
||
When a (sub)object of a non-array type U is specified to have
|
||
an initial value of v, or U(l...),
|
||
where l... is a list of constructor arguments, make_shared shall initialize this (sub)object
|
||
via the expression ::new(pv) U(v) or ::new(pv) U(l...) respectively,
|
||
where pv has type void* and points to storage
|
||
suitable to hold an object of type U[.](#util.smartptr.shared.create-7.4.sentence-1)
|
||
|
||
- [(7.5)](#util.smartptr.shared.create-7.5)
|
||
|
||
When a (sub)object of a non-array type U is specified to have
|
||
an initial value of v, or U(l...),
|
||
where l... is a list of constructor arguments, allocate_shared shall initialize this (sub)object
|
||
via the expression
|
||
* [(7.5.1)](#util.smartptr.shared.create-7.5.1)
|
||
|
||
allocator_traits<A2>::construct(a2, pu, v) or
|
||
|
||
* [(7.5.2)](#util.smartptr.shared.create-7.5.2)
|
||
|
||
allocator_traits<A2>::construct(a2, pu, l...)
|
||
|
||
respectively,
|
||
where pu is a pointer of type remove_cv_t<U>* pointing to storage
|
||
suitable to hold an object of type remove_cv_t<U> and a2 of type A2 is a potentially rebound copy of
|
||
the allocator a passed to allocate_shared[.](#util.smartptr.shared.create-7.5.sentence-1)
|
||
|
||
- [(7.6)](#util.smartptr.shared.create-7.6)
|
||
|
||
When a (sub)object of non-array type U is specified to have
|
||
a default initial value, make_shared shall initialize this (sub)object
|
||
via the expression ::new(pv) U(),
|
||
where pv has type void* and points to storage
|
||
suitable to hold an object of type U[.](#util.smartptr.shared.create-7.6.sentence-1)
|
||
|
||
- [(7.7)](#util.smartptr.shared.create-7.7)
|
||
|
||
When a (sub)object of non-array type U is specified to have
|
||
a default initial value, allocate_shared initializes this (sub)object
|
||
via the expression allocator_traits<A2>::construct(a2, pu),
|
||
where pu is a pointer of type remove_cv_t<U>* pointing to storage
|
||
suitable to hold an object of type remove_cv_t<U> and a2 of type A2 is a potentially rebound copy of
|
||
the allocator a passed to allocate_shared[.](#util.smartptr.shared.create-7.7.sentence-1)
|
||
|
||
- [(7.8)](#util.smartptr.shared.create-7.8)
|
||
|
||
When a (sub)object of non-array type U is initialized by make_shared_for_overwrite or allocate_shared_for_overwrite,
|
||
it is initialized via the expression ::new(pv) U,
|
||
where pv has type void* and
|
||
points to storage suitable to hold an object of type U[.](#util.smartptr.shared.create-7.8.sentence-1)
|
||
|
||
- [(7.9)](#util.smartptr.shared.create-7.9)
|
||
|
||
Array elements are initialized in ascending order of their addresses[.](#util.smartptr.shared.create-7.9.sentence-1)
|
||
|
||
- [(7.10)](#util.smartptr.shared.create-7.10)
|
||
|
||
When the lifetime of the object managed by the return value ends, or
|
||
when the initialization of an array element throws an exception,
|
||
the initialized elements are destroyed in the reverse order
|
||
of their original construction[.](#util.smartptr.shared.create-7.10.sentence-1)
|
||
|
||
- [(7.11)](#util.smartptr.shared.create-7.11)
|
||
|
||
When a (sub)object of non-array type U that was initialized by make_shared, make_shared_for_overwrite, or allocate_shared_for_overwrite is to be destroyed,
|
||
it is destroyed via the expression pu->~U() where pu points to that object of type U[.](#util.smartptr.shared.create-7.11.sentence-1)
|
||
|
||
- [(7.12)](#util.smartptr.shared.create-7.12)
|
||
|
||
When a (sub)object of non-array type U that was initialized by allocate_shared is to be destroyed,
|
||
it is destroyed via the expression allocator_traits<A2>::destroy(a2, pu) where pu is a pointer of type remove_cv_t<U>* pointing to that object of type remove_cv_t<U> and a2 of type A2 is a potentially rebound copy of
|
||
the allocator a passed to allocate_shared[.](#util.smartptr.shared.create-7.12.sentence-1)
|
||
|
||
[*Note [2](#util.smartptr.shared.create-note-2)*:
|
||
|
||
These functions will typically allocate more memory than sizeof(T) to
|
||
allow for internal bookkeeping structures such as reference counts[.](#util.smartptr.shared.create-7.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:make_shared_)
|
||
|
||
`template<class T, class... Args>
|
||
constexpr shared_ptr<T> make_shared(Args&&... args); // T is not array
|
||
template<class T, class A, class... Args>
|
||
constexpr shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
|
||
`
|
||
|
||
[8](#util.smartptr.shared.create-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4380)
|
||
|
||
*Constraints*: T is not an array type[.](#util.smartptr.shared.create-8.sentence-1)
|
||
|
||
[9](#util.smartptr.shared.create-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4384)
|
||
|
||
*Returns*: A shared_ptr to an object of type T with an initial value T(std::forward<Args>(args)...)[.](#util.smartptr.shared.create-9.sentence-1)
|
||
|
||
[10](#util.smartptr.shared.create-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4389)
|
||
|
||
*Remarks*: The shared_ptr constructors called by these functions
|
||
enable shared_from_this with the address of the newly constructed object of type T[.](#util.smartptr.shared.create-10.sentence-1)
|
||
|
||
[11](#util.smartptr.shared.create-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4395)
|
||
|
||
[*Example [1](#util.smartptr.shared.create-example-1)*: shared_ptr<int> p = make_shared<int>(); // shared_ptr to int() shared_ptr<vector<int>> q = make_shared<vector<int>>(16, 1); // shared_ptr to vector of 16 elements with value 1 â *end example*]
|
||
|
||
[ð](#lib:make_shared__)
|
||
|
||
`template<class T>
|
||
constexpr shared_ptr<T> make_shared(size_t N); // T is U[]
|
||
template<class T, class A>
|
||
constexpr shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
|
||
`
|
||
|
||
[12](#util.smartptr.shared.create-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4415)
|
||
|
||
*Constraints*: T is of the form U[][.](#util.smartptr.shared.create-12.sentence-1)
|
||
|
||
[13](#util.smartptr.shared.create-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4419)
|
||
|
||
*Returns*: A shared_ptr to an object of type U[N] with a default initial value,
|
||
where U is remove_extent_t<T>[.](#util.smartptr.shared.create-13.sentence-1)
|
||
|
||
[14](#util.smartptr.shared.create-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4425)
|
||
|
||
[*Example [2](#util.smartptr.shared.create-example-2)*: shared_ptr<double[]> p = make_shared<double[]>(1024); // shared_ptr to a value-initialized double[1024] shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6); // shared_ptr to a value-initialized double[6][2][2] â *end example*]
|
||
|
||
[ð](#lib:make_shared___)
|
||
|
||
`template<class T>
|
||
constexpr shared_ptr<T> make_shared(); // T is U[N]
|
||
template<class T, class A>
|
||
constexpr shared_ptr<T> allocate_shared(const A& a); // T is U[N]
|
||
`
|
||
|
||
[15](#util.smartptr.shared.create-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4446)
|
||
|
||
*Constraints*: T is of the form U[N][.](#util.smartptr.shared.create-15.sentence-1)
|
||
|
||
[16](#util.smartptr.shared.create-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4450)
|
||
|
||
*Returns*: A shared_ptr to an object of type T with a default initial value[.](#util.smartptr.shared.create-16.sentence-1)
|
||
|
||
[17](#util.smartptr.shared.create-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4455)
|
||
|
||
[*Example [3](#util.smartptr.shared.create-example-3)*: shared_ptr<double[1024]> p = make_shared<double[1024]>(); // shared_ptr to a value-initialized double[1024] shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>(); // shared_ptr to a value-initialized double[6][2][2] â *end example*]
|
||
|
||
[ð](#lib:make_shared____)
|
||
|
||
`template<class T>
|
||
constexpr shared_ptr<T> make_shared(size_t N,
|
||
const remove_extent_t<T>& u); // T is U[]
|
||
template<class T, class A>
|
||
constexpr shared_ptr<T> allocate_shared(const A& a, size_t N,
|
||
const remove_extent_t<T>& u); // T is U[]
|
||
`
|
||
|
||
[18](#util.smartptr.shared.create-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4478)
|
||
|
||
*Constraints*: T is of the form U[][.](#util.smartptr.shared.create-18.sentence-1)
|
||
|
||
[19](#util.smartptr.shared.create-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4482)
|
||
|
||
*Returns*: A shared_ptr to an object of type U[N],
|
||
where U is remove_extent_t<T> and
|
||
each array element has an initial value of u[.](#util.smartptr.shared.create-19.sentence-1)
|
||
|
||
[20](#util.smartptr.shared.create-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4488)
|
||
|
||
[*Example [4](#util.smartptr.shared.create-example-4)*: shared_ptr<double[]> p = make_shared<double[]>(1024, 1.0); // shared_ptr to a double[1024], where each element is 1.0 shared_ptr<double[][2]> q = make_shared<double[][2]>(6, {1.0, 0.0}); // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0} shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2}); // shared_ptr to a vector<int>[4], where each vector has contents {1, 2} â *end example*]
|
||
|
||
[ð](#lib:make_shared_____)
|
||
|
||
`template<class T>
|
||
constexpr shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
|
||
template<class T, class A>
|
||
constexpr shared_ptr<T> allocate_shared(const A& a,
|
||
const remove_extent_t<T>& u); // T is U[N]
|
||
`
|
||
|
||
[21](#util.smartptr.shared.create-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4512)
|
||
|
||
*Constraints*: T is of the form U[N][.](#util.smartptr.shared.create-21.sentence-1)
|
||
|
||
[22](#util.smartptr.shared.create-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4516)
|
||
|
||
*Returns*: A shared_ptr to an object of type T,
|
||
where each array element of type remove_extent_t<T> has an initial value of u[.](#util.smartptr.shared.create-22.sentence-1)
|
||
|
||
[23](#util.smartptr.shared.create-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4522)
|
||
|
||
[*Example [5](#util.smartptr.shared.create-example-5)*: shared_ptr<double[1024]> p = make_shared<double[1024]>(1.0); // shared_ptr to a double[1024], where each element is 1.0 shared_ptr<double[6][2]> q = make_shared<double[6][2]>({1.0, 0.0}); // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0} shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2}); // shared_ptr to a vector<int>[4], where each vector has contents {1, 2} â *end example*]
|
||
|
||
[ð](#lib:make_shared______)
|
||
|
||
`template<class T>
|
||
constexpr shared_ptr<T> make_shared_for_overwrite();
|
||
template<class T, class A>
|
||
constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a);
|
||
`
|
||
|
||
[24](#util.smartptr.shared.create-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4545)
|
||
|
||
*Constraints*: T is not an array of unknown bound[.](#util.smartptr.shared.create-24.sentence-1)
|
||
|
||
[25](#util.smartptr.shared.create-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4549)
|
||
|
||
*Returns*: A shared_ptr to an object of type T[.](#util.smartptr.shared.create-25.sentence-1)
|
||
|
||
[26](#util.smartptr.shared.create-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4553)
|
||
|
||
[*Example [6](#util.smartptr.shared.create-example-6)*: struct X { double data[1024]; };
|
||
shared_ptr<X> p = make_shared_for_overwrite<X>(); // shared_ptr to a default-initialized X, where each element in X::data has an indeterminate value shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>(); // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value â *end example*]
|
||
|
||
[ð](#lib:make_shared_______)
|
||
|
||
`template<class T>
|
||
constexpr shared_ptr<T> make_shared_for_overwrite(size_t N);
|
||
template<class T, class A>
|
||
constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
|
||
`
|
||
|
||
[27](#util.smartptr.shared.create-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4576)
|
||
|
||
*Constraints*: T is an array of unknown bound[.](#util.smartptr.shared.create-27.sentence-1)
|
||
|
||
[28](#util.smartptr.shared.create-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4580)
|
||
|
||
*Returns*: A shared_ptr to an object of type U[N],
|
||
where U is remove_extent_t<T>[.](#util.smartptr.shared.create-28.sentence-1)
|
||
|
||
[29](#util.smartptr.shared.create-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4585)
|
||
|
||
[*Example [7](#util.smartptr.shared.create-example-7)*: shared_ptr<double[]> p = make_shared_for_overwrite<double[]>(1024); // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value â *end example*]
|
||
|
||
#### [20.3.2.2.8](#util.smartptr.shared.cmp) Comparison [[util.smartptr.shared.cmp]](util.smartptr.shared.cmp)
|
||
|
||
[ð](#lib:operator==,shared_ptr)
|
||
|
||
`template<class T, class U>
|
||
constexpr bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.shared.cmp-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4603)
|
||
|
||
*Returns*: a.get() == b.get()[.](#util.smartptr.shared.cmp-1.sentence-1)
|
||
|
||
[ð](#lib:operator==,shared_ptr_)
|
||
|
||
`template<class T>
|
||
constexpr bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
|
||
`
|
||
|
||
[2](#util.smartptr.shared.cmp-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4615)
|
||
|
||
*Returns*: !a[.](#util.smartptr.shared.cmp-2.sentence-1)
|
||
|
||
[ð](#lib:operator%3c=%3e,shared_ptr)
|
||
|
||
`template<class T, class U>
|
||
constexpr strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
|
||
`
|
||
|
||
[3](#util.smartptr.shared.cmp-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4627)
|
||
|
||
*Returns*: compare_three_way()(a.get(), b.get())[.](#util.smartptr.shared.cmp-3.sentence-1)
|
||
|
||
[4](#util.smartptr.shared.cmp-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4631)
|
||
|
||
[*Note [1](#util.smartptr.shared.cmp-note-1)*:
|
||
|
||
Defining a comparison operator function allows shared_ptr objects
|
||
to be used as keys in associative containers[.](#util.smartptr.shared.cmp-4.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:operator%3c=%3e,shared_ptr_)
|
||
|
||
`template<class T>
|
||
constexpr strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
|
||
`
|
||
|
||
[5](#util.smartptr.shared.cmp-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4645)
|
||
|
||
*Returns*: compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr))
|
||
|
||
#### [20.3.2.2.9](#util.smartptr.shared.spec) Specialized algorithms [[util.smartptr.shared.spec]](util.smartptr.shared.spec)
|
||
|
||
[ð](#lib:swap,shared_ptr_)
|
||
|
||
`template<class T>
|
||
constexpr void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.shared.spec-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4661)
|
||
|
||
*Effects*: Equivalent to a.swap(b)[.](#util.smartptr.shared.spec-1.sentence-1)
|
||
|
||
#### [20.3.2.2.10](#util.smartptr.shared.cast) Casts [[util.smartptr.shared.cast]](util.smartptr.shared.cast)
|
||
|
||
[ð](#lib:static_pointer_cast,shared_ptr)
|
||
|
||
`template<class T, class U>
|
||
constexpr shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
|
||
template<class T, class U>
|
||
constexpr shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.shared.cast-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4677)
|
||
|
||
*Mandates*: The expression static_cast<T*>((U*)nullptr) is well-formed[.](#util.smartptr.shared.cast-1.sentence-1)
|
||
|
||
[2](#util.smartptr.shared.cast-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4681)
|
||
|
||
*Returns*: shared_ptr<T>(*R*, static_cast<typename shared_ptr<T>::element_type*>(r.get())) where *R* is r for the first overload, andstd::move(r) for the second[.](#util.smartptr.shared.cast-2.sentence-1)
|
||
|
||
[3](#util.smartptr.shared.cast-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4689)
|
||
|
||
[*Note [1](#util.smartptr.shared.cast-note-1)*:
|
||
|
||
The seemingly equivalent expressionshared_ptr<T>(static_cast<T*>(r.get())) can result in undefined behavior, attempting to delete the
|
||
same object twice[.](#util.smartptr.shared.cast-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:dynamic_pointer_cast,shared_ptr)
|
||
|
||
`template<class T, class U>
|
||
constexpr shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
|
||
template<class T, class U>
|
||
constexpr shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
|
||
`
|
||
|
||
[4](#util.smartptr.shared.cast-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4707)
|
||
|
||
*Mandates*: The expression dynamic_cast<T*>((U*)nullptr) is well-formed[.](#util.smartptr.shared.cast-4.sentence-1)
|
||
|
||
The expression dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()) is well-formed[.](#util.smartptr.shared.cast-4.sentence-2)
|
||
|
||
[5](#util.smartptr.shared.cast-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4712)
|
||
|
||
*Preconditions*: The expression dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()) has well-defined behavior[.](#util.smartptr.shared.cast-5.sentence-1)
|
||
|
||
[6](#util.smartptr.shared.cast-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4716)
|
||
|
||
*Returns*:
|
||
|
||
- [(6.1)](#util.smartptr.shared.cast-6.1)
|
||
|
||
When dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()) returns a non-null value p, shared_ptr<T>(*R*, p),
|
||
where *R* is r for the first overload, and std::move(r) for the second[.](#util.smartptr.shared.cast-6.1.sentence-1)
|
||
|
||
- [(6.2)](#util.smartptr.shared.cast-6.2)
|
||
|
||
Otherwise, shared_ptr<T>()[.](#util.smartptr.shared.cast-6.2.sentence-1)
|
||
|
||
[7](#util.smartptr.shared.cast-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4727)
|
||
|
||
[*Note [2](#util.smartptr.shared.cast-note-2)*:
|
||
|
||
The seemingly equivalent expressionshared_ptr<T>(dynamic_cast<T*>(r.get())) can result in
|
||
undefined behavior, attempting to delete the same object twice[.](#util.smartptr.shared.cast-7.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:const_pointer_cast,shared_ptr)
|
||
|
||
`template<class T, class U>
|
||
constexpr shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
|
||
template<class T, class U>
|
||
constexpr shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
|
||
`
|
||
|
||
[8](#util.smartptr.shared.cast-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4744)
|
||
|
||
*Mandates*: The expression const_cast<T*>((U*)nullptr) is well-formed[.](#util.smartptr.shared.cast-8.sentence-1)
|
||
|
||
[9](#util.smartptr.shared.cast-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4748)
|
||
|
||
*Returns*: shared_ptr<T>(*R*, const_cast<typename shared_ptr<T>::element_type*>(r.get())) where *R* is r for the first overload, andstd::move(r) for the second[.](#util.smartptr.shared.cast-9.sentence-1)
|
||
|
||
[10](#util.smartptr.shared.cast-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4756)
|
||
|
||
[*Note [3](#util.smartptr.shared.cast-note-3)*:
|
||
|
||
The seemingly equivalent expressionshared_ptr<T>(const_cast<T*>(r.get())) can result in
|
||
undefined behavior, attempting to delete the same object twice[.](#util.smartptr.shared.cast-10.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:reinterpret_pointer_cast,shared_ptr)
|
||
|
||
`template<class T, class U>
|
||
shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
|
||
template<class T, class U>
|
||
shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
|
||
`
|
||
|
||
[11](#util.smartptr.shared.cast-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4773)
|
||
|
||
*Mandates*: The expression reinterpret_cast<T*>((U*)nullptr) is well-formed[.](#util.smartptr.shared.cast-11.sentence-1)
|
||
|
||
[12](#util.smartptr.shared.cast-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4777)
|
||
|
||
*Returns*: shared_ptr<T>(*R*, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get())) where *R* is r for the first overload, andstd::move(r) for the second[.](#util.smartptr.shared.cast-12.sentence-1)
|
||
|
||
[13](#util.smartptr.shared.cast-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4785)
|
||
|
||
[*Note [4](#util.smartptr.shared.cast-note-4)*:
|
||
|
||
The seemingly equivalent expressionshared_ptr<T>(reinterpret_cast<T*>(r.get())) can result in
|
||
undefined behavior, attempting to delete the same object twice[.](#util.smartptr.shared.cast-13.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.2.2.11](#util.smartptr.getdeleter) get_deleter [[util.smartptr.getdeleter]](util.smartptr.getdeleter)
|
||
|
||
[ð](#lib:get_deleter,shared_ptr)
|
||
|
||
`template<class D, class T>
|
||
constexpr D* get_deleter(const shared_ptr<T>& p) noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.getdeleter-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4802)
|
||
|
||
*Returns*: If p owns a deleter d of type cv-unqualifiedD, returns addressof(d); otherwise returns nullptr[.](#util.smartptr.getdeleter-1.sentence-1)
|
||
|
||
The returned
|
||
pointer remains valid as long as there exists a shared_ptr instance
|
||
that owns d[.](#util.smartptr.getdeleter-1.sentence-2)
|
||
|
||
[*Note [1](#util.smartptr.getdeleter-note-1)*:
|
||
|
||
It is unspecified whether the pointer
|
||
remains valid longer than that[.](#util.smartptr.getdeleter-1.sentence-3)
|
||
|
||
This can happen if the implementation doesn't destroy
|
||
the deleter until all weak_ptr instances that share ownership withp have been destroyed[.](#util.smartptr.getdeleter-1.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.2.2.12](#util.smartptr.shared.io) I/O [[util.smartptr.shared.io]](util.smartptr.shared.io)
|
||
|
||
[ð](#lib:operator%3c%3c,shared_ptr)
|
||
|
||
`template<class E, class T, class Y>
|
||
basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p);
|
||
`
|
||
|
||
[1](#util.smartptr.shared.io-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4826)
|
||
|
||
*Effects*: As if by: os << p.get();
|
||
|
||
[2](#util.smartptr.shared.io-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4830)
|
||
|
||
*Returns*: os[.](#util.smartptr.shared.io-2.sentence-1)
|
||
|
||
#### [20.3.2.3](#util.smartptr.weak) Class template weak_ptr [[util.smartptr.weak]](util.smartptr.weak)
|
||
|
||
#### [20.3.2.3.1](#util.smartptr.weak.general) General [[util.smartptr.weak.general]](util.smartptr.weak.general)
|
||
|
||
[1](#util.smartptr.weak.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4839)
|
||
|
||
The weak_ptr class template stores a weak reference to an object
|
||
that is already managed by a shared_ptr[.](#util.smartptr.weak.general-1.sentence-1)
|
||
|
||
To access the object, aweak_ptr can be converted to a shared_ptr using the member
|
||
function lock[.](#util.smartptr.weak.general-1.sentence-2)
|
||
|
||
namespace std {template<class T> class weak_ptr {public:using element_type = remove_extent_t<T>; // [[util.smartptr.weak.const]](#util.smartptr.weak.const "20.3.2.3.2 Constructors"), constructorsconstexpr weak_ptr() noexcept; template<class Y>constexpr weak_ptr(const shared_ptr<Y>& r) noexcept; constexpr weak_ptr(const weak_ptr& r) noexcept; template<class Y>constexpr weak_ptr(const weak_ptr<Y>& r) noexcept; constexpr weak_ptr(weak_ptr&& r) noexcept; template<class Y>constexpr weak_ptr(weak_ptr<Y>&& r) noexcept; // [[util.smartptr.weak.dest]](#util.smartptr.weak.dest "20.3.2.3.3 Destructor"), destructorconstexpr ~weak_ptr(); // [[util.smartptr.weak.assign]](#util.smartptr.weak.assign "20.3.2.3.4 Assignment"), assignmentconstexpr weak_ptr& operator=(const weak_ptr& r) noexcept; template<class Y>constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept; template<class Y>constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept; constexpr weak_ptr& operator=(weak_ptr&& r) noexcept; template<class Y>constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // [[util.smartptr.weak.mod]](#util.smartptr.weak.mod "20.3.2.3.5 Modifiers"), modifiersconstexpr void swap(weak_ptr& r) noexcept; constexpr void reset() noexcept; // [[util.smartptr.weak.obs]](#util.smartptr.weak.obs "20.3.2.3.6 Observers"), observersconstexpr long use_count() const noexcept; constexpr bool expired() const noexcept; constexpr shared_ptr<T> lock() 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> weak_ptr(shared_ptr<T>) -> weak_ptr<T>;}
|
||
|
||
[2](#util.smartptr.weak.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4900)
|
||
|
||
Specializations of weak_ptr shall be [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and[*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]"), allowing their use in standard
|
||
containers[.](#util.smartptr.weak.general-2.sentence-1)
|
||
|
||
The template parameter T of weak_ptr may be an
|
||
incomplete type[.](#util.smartptr.weak.general-2.sentence-2)
|
||
|
||
#### [20.3.2.3.2](#util.smartptr.weak.const) Constructors [[util.smartptr.weak.const]](util.smartptr.weak.const)
|
||
|
||
[ð](#lib:weak_ptr,constructor)
|
||
|
||
`constexpr weak_ptr() noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.weak.const-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4914)
|
||
|
||
*Effects*: Constructs an empty weak_ptr object that stores a null pointer value[.](#util.smartptr.weak.const-1.sentence-1)
|
||
|
||
[2](#util.smartptr.weak.const-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4918)
|
||
|
||
*Postconditions*: use_count() == 0[.](#util.smartptr.weak.const-2.sentence-1)
|
||
|
||
[ð](#lib:weak_ptr,constructor_)
|
||
|
||
`constexpr weak_ptr(const weak_ptr& r) noexcept;
|
||
template<class Y> constexpr weak_ptr(const weak_ptr<Y>& r) noexcept;
|
||
template<class Y> constexpr weak_ptr(const shared_ptr<Y>& r) noexcept;
|
||
`
|
||
|
||
[3](#util.smartptr.weak.const-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4931)
|
||
|
||
*Constraints*: For the second and third constructors, Y* is compatible with T*[.](#util.smartptr.weak.const-3.sentence-1)
|
||
|
||
[4](#util.smartptr.weak.const-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4935)
|
||
|
||
*Effects*: If r is empty, constructs
|
||
an empty weak_ptr object that stores a null pointer value;
|
||
otherwise, constructs
|
||
a weak_ptr object that shares ownership
|
||
with r and stores a copy of the pointer stored in r[.](#util.smartptr.weak.const-4.sentence-1)
|
||
|
||
[5](#util.smartptr.weak.const-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4943)
|
||
|
||
*Postconditions*: use_count() == r.use_count()[.](#util.smartptr.weak.const-5.sentence-1)
|
||
|
||
[ð](#lib:weak_ptr,constructor__)
|
||
|
||
`constexpr weak_ptr(weak_ptr&& r) noexcept;
|
||
template<class Y> constexpr weak_ptr(weak_ptr<Y>&& r) noexcept;
|
||
`
|
||
|
||
[6](#util.smartptr.weak.const-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4955)
|
||
|
||
*Constraints*: For the second constructor, Y* is compatible with T*[.](#util.smartptr.weak.const-6.sentence-1)
|
||
|
||
[7](#util.smartptr.weak.const-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4959)
|
||
|
||
*Effects*: Move constructs a weak_ptr instance from r[.](#util.smartptr.weak.const-7.sentence-1)
|
||
|
||
[8](#util.smartptr.weak.const-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4963)
|
||
|
||
*Postconditions*: *this contains the old value of r[.](#util.smartptr.weak.const-8.sentence-1)
|
||
|
||
r is empty, stores a null pointer value, and r.use_count() == 0[.](#util.smartptr.weak.const-8.sentence-2)
|
||
|
||
#### [20.3.2.3.3](#util.smartptr.weak.dest) Destructor [[util.smartptr.weak.dest]](util.smartptr.weak.dest)
|
||
|
||
[ð](#lib:weak_ptr,destructor)
|
||
|
||
`constexpr ~weak_ptr();
|
||
`
|
||
|
||
[1](#util.smartptr.weak.dest-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4977)
|
||
|
||
*Effects*: Destroys this weak_ptr object but has no
|
||
effect on the object its stored pointer points to[.](#util.smartptr.weak.dest-1.sentence-1)
|
||
|
||
#### [20.3.2.3.4](#util.smartptr.weak.assign) Assignment [[util.smartptr.weak.assign]](util.smartptr.weak.assign)
|
||
|
||
[ð](#lib:operator=,weak_ptr)
|
||
|
||
`constexpr weak_ptr& operator=(const weak_ptr& r) noexcept;
|
||
template<class Y> constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
|
||
template<class Y> constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.weak.assign-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4993)
|
||
|
||
*Effects*: Equivalent to weak_ptr(r).swap(*this)[.](#util.smartptr.weak.assign-1.sentence-1)
|
||
|
||
[2](#util.smartptr.weak.assign-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L4997)
|
||
|
||
*Returns*: *this[.](#util.smartptr.weak.assign-2.sentence-1)
|
||
|
||
[3](#util.smartptr.weak.assign-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5001)
|
||
|
||
*Remarks*: The implementation may meet the effects (and the
|
||
implied guarantees) via different means, without creating a temporary object[.](#util.smartptr.weak.assign-3.sentence-1)
|
||
|
||
[ð](#lib:operator=,weak_ptr_)
|
||
|
||
`constexpr weak_ptr& operator=(weak_ptr&& r) noexcept;
|
||
template<class Y> constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
|
||
`
|
||
|
||
[4](#util.smartptr.weak.assign-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5014)
|
||
|
||
*Effects*: Equivalent to weak_ptr(std::move(r)).swap(*this)[.](#util.smartptr.weak.assign-4.sentence-1)
|
||
|
||
[5](#util.smartptr.weak.assign-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5018)
|
||
|
||
*Returns*: *this[.](#util.smartptr.weak.assign-5.sentence-1)
|
||
|
||
#### [20.3.2.3.5](#util.smartptr.weak.mod) Modifiers [[util.smartptr.weak.mod]](util.smartptr.weak.mod)
|
||
|
||
[ð](#lib:swap,weak_ptr)
|
||
|
||
`constexpr void swap(weak_ptr& r) noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.weak.mod-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5030)
|
||
|
||
*Effects*: Exchanges the contents of *this and r[.](#util.smartptr.weak.mod-1.sentence-1)
|
||
|
||
[ð](#lib:reset,weak_ptr)
|
||
|
||
`constexpr void reset() noexcept;
|
||
`
|
||
|
||
[2](#util.smartptr.weak.mod-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5041)
|
||
|
||
*Effects*: Equivalent to weak_ptr().swap(*this)[.](#util.smartptr.weak.mod-2.sentence-1)
|
||
|
||
#### [20.3.2.3.6](#util.smartptr.weak.obs) Observers [[util.smartptr.weak.obs]](util.smartptr.weak.obs)
|
||
|
||
[ð](#lib:use_count,weak_ptr)
|
||
|
||
`constexpr long use_count() const noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.weak.obs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5053)
|
||
|
||
*Returns*: 0 if *this is empty;
|
||
otherwise, the number of shared_ptr instances
|
||
that share ownership with *this[.](#util.smartptr.weak.obs-1.sentence-1)
|
||
|
||
[ð](#lib:expired,weak_ptr)
|
||
|
||
`constexpr bool expired() const noexcept;
|
||
`
|
||
|
||
[2](#util.smartptr.weak.obs-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5066)
|
||
|
||
*Returns*: use_count() == 0[.](#util.smartptr.weak.obs-2.sentence-1)
|
||
|
||
[ð](#lib:lock,weak_ptr)
|
||
|
||
`constexpr shared_ptr<T> lock() const noexcept;
|
||
`
|
||
|
||
[3](#util.smartptr.weak.obs-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5077)
|
||
|
||
*Returns*: expired() ? shared_ptr<T>() : shared_ptr<T>(*this), executed atomically[.](#util.smartptr.weak.obs-3.sentence-1)
|
||
|
||
[ð](#lib:owner_before,weak_ptr)
|
||
|
||
`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;
|
||
`
|
||
|
||
[4](#util.smartptr.weak.obs-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5089)
|
||
|
||
*Returns*: An unspecified value such that
|
||
|
||
- [(4.1)](#util.smartptr.weak.obs-4.1)
|
||
|
||
owner_before(b) defines a strict weak ordering as defined in [[alg.sorting]](alg.sorting "26.8 Sorting and related operations");
|
||
|
||
- [(4.2)](#util.smartptr.weak.obs-4.2)
|
||
|
||
!owner_before(b) && !b.owner_before(*this) is true if and only if owner_equal(b) is true[.](#util.smartptr.weak.obs-4.sentence-1)
|
||
|
||
[ð](#lib:owner_hash,weak_ptr)
|
||
|
||
`size_t owner_hash() const noexcept;
|
||
`
|
||
|
||
[5](#util.smartptr.weak.obs-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5106)
|
||
|
||
*Returns*: An unspecified value such that,
|
||
for any object x where owner_equal(x) is true,owner_hash() == x.owner_hash() is true[.](#util.smartptr.weak.obs-5.sentence-1)
|
||
|
||
[ð](#lib:owner_equal,weak_ptr)
|
||
|
||
`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;
|
||
`
|
||
|
||
[6](#util.smartptr.weak.obs-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5122)
|
||
|
||
*Returns*: true if and only if*this and b share ownership or are both empty[.](#util.smartptr.weak.obs-6.sentence-1)
|
||
|
||
Otherwise returns false[.](#util.smartptr.weak.obs-6.sentence-2)
|
||
|
||
[7](#util.smartptr.weak.obs-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5128)
|
||
|
||
*Remarks*: owner_equal is an equivalence relation[.](#util.smartptr.weak.obs-7.sentence-1)
|
||
|
||
#### [20.3.2.3.7](#util.smartptr.weak.spec) Specialized algorithms [[util.smartptr.weak.spec]](util.smartptr.weak.spec)
|
||
|
||
[ð](#lib:swap,weak_ptr_)
|
||
|
||
`template<class T>
|
||
constexpr void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
|
||
`
|
||
|
||
[1](#util.smartptr.weak.spec-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5142)
|
||
|
||
*Effects*: Equivalent to a.swap(b)[.](#util.smartptr.weak.spec-1.sentence-1)
|
||
|
||
#### [20.3.2.4](#util.smartptr.ownerless) Class template owner_less [[util.smartptr.ownerless]](util.smartptr.ownerless)
|
||
|
||
[1](#util.smartptr.ownerless-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5149)
|
||
|
||
The class template owner_less allows ownership-based mixed comparisons of shared
|
||
and weak pointers[.](#util.smartptr.ownerless-1.sentence-1)
|
||
|
||
[ð](#lib:owner_less)
|
||
|
||
namespace std {template<class T = void> struct owner_less; template<class T> struct owner_less<shared_ptr<T>> {constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept; constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept; constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept; }; template<class T> struct owner_less<weak_ptr<T>> {constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept; constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept; constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept; }; template<> struct owner_less<void> {template<class T, class U>constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept; using is_transparent = *unspecified*; };}
|
||
|
||
[2](#util.smartptr.ownerless-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5186)
|
||
|
||
operator()(x, y) returns x.owner_before(y)[.](#util.smartptr.ownerless-2.sentence-1)
|
||
|
||
[*Note [1](#util.smartptr.ownerless-note-1)*:
|
||
|
||
Note that
|
||
|
||
- [(2.1)](#util.smartptr.ownerless-2.1)
|
||
|
||
operator() defines a strict weak ordering as defined in [[alg.sorting]](alg.sorting "26.8 Sorting and related operations");
|
||
|
||
- [(2.2)](#util.smartptr.ownerless-2.2)
|
||
|
||
!operator()(a, b) && !operator()(b, a) is true if and only if a.owner_equal(b) is true[.](#util.smartptr.ownerless-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.2.5](#util.smartptr.owner.hash) Struct owner_hash [[util.smartptr.owner.hash]](util.smartptr.owner.hash)
|
||
|
||
[1](#util.smartptr.owner.hash-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5201)
|
||
|
||
The class owner_hash provides ownership-based hashing[.](#util.smartptr.owner.hash-1.sentence-1)
|
||
|
||
[ð](#lib:owner_hash)
|
||
|
||
namespace std {struct owner_hash {template<class T> size_t operator()(const shared_ptr<T>&) const noexcept; template<class T> size_t operator()(const weak_ptr<T>&) const noexcept; using is_transparent = *unspecified*; };}
|
||
|
||
[ð](#lib:operator(),owner_hash)
|
||
|
||
`template<class T>
|
||
size_t operator()(const shared_ptr<T>& x) const noexcept;
|
||
template<class T>
|
||
size_t operator()(const weak_ptr<T>& x) const noexcept;
|
||
`
|
||
|
||
[2](#util.smartptr.owner.hash-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5228)
|
||
|
||
*Returns*: x.owner_hash()[.](#util.smartptr.owner.hash-2.sentence-1)
|
||
|
||
[3](#util.smartptr.owner.hash-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5232)
|
||
|
||
[*Note [1](#util.smartptr.owner.hash-note-1)*:
|
||
|
||
For any object y where x.owner_equal(y) is true,x.owner_hash() == y.owner_hash() is true[.](#util.smartptr.owner.hash-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.2.6](#util.smartptr.owner.equal) Struct owner_equal [[util.smartptr.owner.equal]](util.smartptr.owner.equal)
|
||
|
||
[1](#util.smartptr.owner.equal-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5241)
|
||
|
||
The class owner_equal provides
|
||
ownership-based mixed equality comparisons of shared and weak pointers[.](#util.smartptr.owner.equal-1.sentence-1)
|
||
|
||
[ð](#lib:owner_equal)
|
||
|
||
namespace std {struct owner_equal {template<class T, class U>constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept; template<class T, class U>constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept; using is_transparent = *unspecified*; };}
|
||
|
||
[ð](#lib:operator(),owner_equal)
|
||
|
||
`template<class T, class U>
|
||
constexpr bool operator()(const shared_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
|
||
template<class T, class U>
|
||
constexpr bool operator()(const shared_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
|
||
template<class T, class U>
|
||
constexpr bool operator()(const weak_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
|
||
template<class T, class U>
|
||
constexpr bool operator()(const weak_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
|
||
`
|
||
|
||
[2](#util.smartptr.owner.equal-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5276)
|
||
|
||
*Returns*: x.owner_equal(y)[.](#util.smartptr.owner.equal-2.sentence-1)
|
||
|
||
[3](#util.smartptr.owner.equal-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5280)
|
||
|
||
[*Note [1](#util.smartptr.owner.equal-note-1)*:
|
||
|
||
x.owner_equal(y) is true if and only if x and y share ownership or are both empty[.](#util.smartptr.owner.equal-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.2.7](#util.smartptr.enab) Class template enable_shared_from_this [[util.smartptr.enab]](util.smartptr.enab)
|
||
|
||
[1](#util.smartptr.enab-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5289)
|
||
|
||
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[.](#util.smartptr.enab-1.sentence-1)
|
||
|
||
[2](#util.smartptr.enab-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5295)
|
||
|
||
[*Example [1](#util.smartptr.enab-example-1)*: 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.owner_equal(q)); // p and q share ownership} â *end example*]
|
||
|
||
namespace std {template<class T> class enable_shared_from_this {protected:constexpr enable_shared_from_this() noexcept; constexpr enable_shared_from_this(const enable_shared_from_this&) noexcept; constexpr enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept; constexpr ~enable_shared_from_this(); public:constexpr shared_ptr<T> shared_from_this(); constexpr shared_ptr<T const> shared_from_this() const; constexpr weak_ptr<T> weak_from_this() noexcept; constexpr weak_ptr<T const> weak_from_this() const noexcept; private:mutable weak_ptr<T> *weak-this*; // *exposition only*};}
|
||
|
||
[3](#util.smartptr.enab-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5330)
|
||
|
||
The template parameter T of enable_shared_from_this may be an incomplete type[.](#util.smartptr.enab-3.sentence-1)
|
||
|
||
[ð](#lib:enable_shared_from_this,constructor)
|
||
|
||
`constexpr enable_shared_from_this() noexcept;
|
||
constexpr enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
|
||
`
|
||
|
||
[4](#util.smartptr.enab-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5341)
|
||
|
||
*Effects*: Value-initializes *weak-this*[.](#util.smartptr.enab-4.sentence-1)
|
||
|
||
[ð](#lib:operator=,enable_shared_from_this)
|
||
|
||
`constexpr enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
|
||
`
|
||
|
||
[5](#util.smartptr.enab-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5352)
|
||
|
||
*Returns*: *this[.](#util.smartptr.enab-5.sentence-1)
|
||
|
||
[6](#util.smartptr.enab-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5356)
|
||
|
||
[*Note [1](#util.smartptr.enab-note-1)*:
|
||
|
||
*weak-this* is not changed[.](#util.smartptr.enab-6.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:shared_ptr_)
|
||
|
||
`constexpr shared_ptr<T> shared_from_this();
|
||
constexpr shared_ptr<T const> shared_from_this() const;
|
||
`
|
||
|
||
[7](#util.smartptr.enab-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5370)
|
||
|
||
*Returns*: shared_ptr<T>(*weak-this*)[.](#util.smartptr.enab-7.sentence-1)
|
||
|
||
[ð](#lib:weak_ptr__)
|
||
|
||
`constexpr weak_ptr<T> weak_from_this() noexcept;
|
||
constexpr weak_ptr<T const> weak_from_this() const noexcept;
|
||
`
|
||
|
||
[8](#util.smartptr.enab-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5383)
|
||
|
||
*Returns*: *weak-this*[.](#util.smartptr.enab-8.sentence-1)
|