3791 lines
154 KiB
Markdown
3791 lines
154 KiB
Markdown
[smartptr]
|
||
|
||
# 20 Memory management library [[mem]](./#mem)
|
||
|
||
## 20.3 Smart pointers [smartptr]
|
||
|
||
### [20.3.1](#unique.ptr) Unique-ownership pointers [[unique.ptr]](unique.ptr)
|
||
|
||
#### [20.3.1.1](#unique.ptr.general) General [[unique.ptr.general]](unique.ptr.general)
|
||
|
||
[1](#unique.ptr.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2217)
|
||
|
||
A [*unique pointer*](#def:unique_pointer "20.3.1.1 General [unique.ptr.general]") is an object that owns another object and
|
||
manages that other object through a pointer[.](#unique.ptr.general-1.sentence-1)
|
||
|
||
More precisely, a unique pointer
|
||
is an object *u* that stores a pointer to a second object *p* and
|
||
will dispose of *p* when *u* is itself destroyed (e.g., when
|
||
leaving block scope ([[stmt.dcl]](stmt.dcl "8.10 Declaration statement")))[.](#unique.ptr.general-1.sentence-2)
|
||
|
||
In this context, *u* is said
|
||
to [*own*](#def:own "20.3.1.1 General [unique.ptr.general]") p[.](#unique.ptr.general-1.sentence-3)
|
||
|
||
[2](#unique.ptr.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2225)
|
||
|
||
The mechanism by which *u* disposes of *p* is known as*p*'s associated [*deleter*](#def:deleter "20.3.1.1 General [unique.ptr.general]"), a function object whose correct
|
||
invocation results in *p*'s appropriate disposition (typically its deletion)[.](#unique.ptr.general-2.sentence-1)
|
||
|
||
[3](#unique.ptr.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2230)
|
||
|
||
Let the notation *u.p* denote the pointer stored by *u*, and
|
||
let *u.d* denote the associated deleter[.](#unique.ptr.general-3.sentence-1)
|
||
|
||
Upon request, *u* can[*reset*](#def:reset "20.3.1.1 General [unique.ptr.general]") (replace) *u.p* and *u.d* with another pointer and
|
||
deleter, but properly disposes of its owned object via the associated
|
||
deleter before such replacement is considered completed[.](#unique.ptr.general-3.sentence-2)
|
||
|
||
[4](#unique.ptr.general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2237)
|
||
|
||
Each object of a type U instantiated from the unique_ptr template
|
||
specified in [[unique.ptr]](#unique.ptr "20.3.1 Unique-ownership pointers") has the strict ownership semantics, specified above,
|
||
of a unique pointer[.](#unique.ptr.general-4.sentence-1)
|
||
|
||
In partial satisfaction of these semantics, each such U is [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and [*Cpp17MoveAssignable*](utility.arg.requirements#:Cpp17MoveAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]"), but is not[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") nor [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]")[.](#unique.ptr.general-4.sentence-2)
|
||
|
||
The template parameter T of unique_ptr may be an incomplete type[.](#unique.ptr.general-4.sentence-3)
|
||
|
||
[5](#unique.ptr.general-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2245)
|
||
|
||
[*Note [1](#unique.ptr.general-note-1)*:
|
||
|
||
The uses
|
||
of unique_ptr include providing exception safety for
|
||
dynamically allocated memory, passing ownership of dynamically allocated
|
||
memory to a function, and returning dynamically allocated memory from a
|
||
function[.](#unique.ptr.general-5.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.1.2](#unique.ptr.dltr) Default deleters [[unique.ptr.dltr]](unique.ptr.dltr)
|
||
|
||
#### [20.3.1.2.1](#unique.ptr.dltr.general) General [[unique.ptr.dltr.general]](unique.ptr.dltr.general)
|
||
|
||
[1](#unique.ptr.dltr.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2258)
|
||
|
||
The class template default_delete serves as the default deleter (destruction policy)
|
||
for the class template unique_ptr[.](#unique.ptr.dltr.general-1.sentence-1)
|
||
|
||
[2](#unique.ptr.dltr.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2262)
|
||
|
||
The template parameter T of default_delete may be
|
||
an incomplete type[.](#unique.ptr.dltr.general-2.sentence-1)
|
||
|
||
#### [20.3.1.2.2](#unique.ptr.dltr.dflt) default_delete [[unique.ptr.dltr.dflt]](unique.ptr.dltr.dflt)
|
||
|
||
namespace std {template<class T> struct default_delete {constexpr default_delete() noexcept = default; template<class U> constexpr default_delete(const default_delete<U>&) noexcept; constexpr void operator()(T*) const; };}
|
||
|
||
[ð](#lib:default_delete,constructor)
|
||
|
||
`template<class U> constexpr default_delete(const default_delete<U>& other) noexcept;
|
||
`
|
||
|
||
[1](#unique.ptr.dltr.dflt-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2284)
|
||
|
||
*Constraints*: U* is implicitly convertible to T*[.](#unique.ptr.dltr.dflt-1.sentence-1)
|
||
|
||
[2](#unique.ptr.dltr.dflt-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2288)
|
||
|
||
*Effects*: Constructs a default_delete object
|
||
from another default_delete<U> object[.](#unique.ptr.dltr.dflt-2.sentence-1)
|
||
|
||
[ð](#lib:operator(),default_delete)
|
||
|
||
`constexpr void operator()(T* ptr) const;
|
||
`
|
||
|
||
[3](#unique.ptr.dltr.dflt-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2300)
|
||
|
||
*Mandates*: T is a complete type[.](#unique.ptr.dltr.dflt-3.sentence-1)
|
||
|
||
[4](#unique.ptr.dltr.dflt-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2304)
|
||
|
||
*Effects*: Calls delete on ptr[.](#unique.ptr.dltr.dflt-4.sentence-1)
|
||
|
||
#### [20.3.1.2.3](#unique.ptr.dltr.dflt1) default_delete<T[]> [[unique.ptr.dltr.dflt1]](unique.ptr.dltr.dflt1)
|
||
|
||
namespace std {template<class T> struct default_delete<T[]> {constexpr default_delete() noexcept = default; template<class U> constexpr default_delete(const default_delete<U[]>&) noexcept; template<class U> constexpr void operator()(U* ptr) const; };}
|
||
|
||
[ð](#lib:default_delete,constructor_)
|
||
|
||
`template<class U> constexpr default_delete(const default_delete<U[]>& other) noexcept;
|
||
`
|
||
|
||
[1](#unique.ptr.dltr.dflt1-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2327)
|
||
|
||
*Constraints*: U(*)[] is convertible to T(*)[][.](#unique.ptr.dltr.dflt1-1.sentence-1)
|
||
|
||
[2](#unique.ptr.dltr.dflt1-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2331)
|
||
|
||
*Effects*: Constructs a default_delete object from another default_delete<U[]> object[.](#unique.ptr.dltr.dflt1-2.sentence-1)
|
||
|
||
[ð](#lib:operator(),default_delete_)
|
||
|
||
`template<class U> constexpr void operator()(U* ptr) const;
|
||
`
|
||
|
||
[3](#unique.ptr.dltr.dflt1-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2342)
|
||
|
||
*Constraints*: U(*)[] is convertible to T(*)[][.](#unique.ptr.dltr.dflt1-3.sentence-1)
|
||
|
||
[4](#unique.ptr.dltr.dflt1-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2346)
|
||
|
||
*Mandates*: U is a complete type[.](#unique.ptr.dltr.dflt1-4.sentence-1)
|
||
|
||
[5](#unique.ptr.dltr.dflt1-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2350)
|
||
|
||
*Effects*: Calls delete[] on ptr[.](#unique.ptr.dltr.dflt1-5.sentence-1)
|
||
|
||
#### [20.3.1.3](#unique.ptr.single) unique_ptr for single objects [[unique.ptr.single]](unique.ptr.single)
|
||
|
||
#### [20.3.1.3.1](#unique.ptr.single.general) General [[unique.ptr.single.general]](unique.ptr.single.general)
|
||
|
||
[ð](#lib:unique_ptr)
|
||
|
||
namespace std {template<class T, class D = default_delete<T>> class unique_ptr {public:using pointer = *see below*; using element_type = T; using deleter_type = D; // [[unique.ptr.single.ctor]](#unique.ptr.single.ctor "20.3.1.3.2 Constructors"), constructorsconstexpr unique_ptr() noexcept; constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept; constexpr unique_ptr(type_identity_t<pointer> p, *see below* d1) noexcept; constexpr unique_ptr(type_identity_t<pointer> p, *see below* d2) noexcept; constexpr unique_ptr(unique_ptr&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; template<class U, class E>constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept; // [[unique.ptr.single.dtor]](#unique.ptr.single.dtor "20.3.1.3.3 Destructor"), destructorconstexpr ~unique_ptr(); // [[unique.ptr.single.asgn]](#unique.ptr.single.asgn "20.3.1.3.4 Assignment"), assignmentconstexpr unique_ptr& operator=(unique_ptr&& u) noexcept; template<class U, class E>constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; constexpr unique_ptr& operator=(nullptr_t) noexcept; // [[unique.ptr.single.observers]](#unique.ptr.single.observers "20.3.1.3.5 Observers"), observersconstexpr add_lvalue_reference_t<T> operator*() const noexcept(*see below*); constexpr pointer operator->() const noexcept; constexpr pointer get() const noexcept; constexpr deleter_type& get_deleter() noexcept; constexpr const deleter_type& get_deleter() const noexcept; constexpr explicit operator bool() const noexcept; // [[unique.ptr.single.modifiers]](#unique.ptr.single.modifiers "20.3.1.3.6 Modifiers"), modifiersconstexpr pointer release() noexcept; constexpr void reset(pointer p = pointer()) noexcept; constexpr void swap(unique_ptr& u) noexcept; // disable copy from lvalue unique_ptr(const unique_ptr&) = delete;
|
||
unique_ptr& operator=(const unique_ptr&) = delete; };}
|
||
|
||
[1](#unique.ptr.single.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2407)
|
||
|
||
A program that instantiates the definition of unique_ptr<T, D> is ill-formed if T* is an invalid type[.](#unique.ptr.single.general-1.sentence-1)
|
||
|
||
[*Note [1](#unique.ptr.single.general-note-1)*:
|
||
|
||
This prevents the instantiation of specializations such asunique_ptr<T&, D> and unique_ptr<int() const, D>[.](#unique.ptr.single.general-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#unique.ptr.single.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2415)
|
||
|
||
The default type for the template parameter D isdefault_delete[.](#unique.ptr.single.general-2.sentence-1)
|
||
|
||
A client-supplied template argumentD shall be a function
|
||
object type ([[function.objects]](function.objects "22.10 Function objects")), lvalue reference to function, or
|
||
lvalue reference to function object type
|
||
for which, given
|
||
a value d of type D and a valueptr of type unique_ptr<T, D>::pointer, the expressiond(ptr) is valid and has the effect of disposing of the
|
||
pointer as appropriate for that deleter[.](#unique.ptr.single.general-2.sentence-2)
|
||
|
||
[3](#unique.ptr.single.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2427)
|
||
|
||
If the deleter's type D is not a reference type, D shall meet
|
||
the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [35](utility.arg.requirements#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements"))[.](#unique.ptr.single.general-3.sentence-1)
|
||
|
||
[4](#unique.ptr.single.general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2431)
|
||
|
||
If the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") remove_reference_t<D>::pointer is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")), then unique_ptr<T,
|
||
D>::pointer shall be a synonym for remove_reference_t<D>::pointer[.](#unique.ptr.single.general-4.sentence-1)
|
||
|
||
Otherwiseunique_ptr<T, D>::pointer shall be a synonym for element_type*[.](#unique.ptr.single.general-4.sentence-2)
|
||
|
||
The type unique_ptr<T,
|
||
D>::pointer shall
|
||
meet the [*Cpp17NullablePointer*](nullablepointer.requirements#:Cpp17NullablePointer "16.4.4.4 Cpp17NullablePointer requirements [nullablepointer.requirements]") requirements (Table [36](nullablepointer.requirements#tab:cpp17.nullablepointer "Table 36: Cpp17NullablePointer requirements"))[.](#unique.ptr.single.general-4.sentence-3)
|
||
|
||
[5](#unique.ptr.single.general-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2439)
|
||
|
||
[*Example [1](#unique.ptr.single.general-example-1)*:
|
||
|
||
Given an allocator type X ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General")) and
|
||
letting A be a synonym for allocator_traits<X>, the types A::pointer,A::const_pointer, A::void_pointer, and A::const_void_pointer may be used as unique_ptr<T, D>::pointer[.](#unique.ptr.single.general-5.sentence-1)
|
||
|
||
â *end example*]
|
||
|
||
#### [20.3.1.3.2](#unique.ptr.single.ctor) Constructors [[unique.ptr.single.ctor]](unique.ptr.single.ctor)
|
||
|
||
[ð](#lib:unique_ptr,constructor)
|
||
|
||
`constexpr unique_ptr() noexcept;
|
||
constexpr unique_ptr(nullptr_t) noexcept;
|
||
`
|
||
|
||
[1](#unique.ptr.single.ctor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2456)
|
||
|
||
*Constraints*: is_pointer_v<deleter_type> is false andis_default_constructible_v<deleter_type> is true[.](#unique.ptr.single.ctor-1.sentence-1)
|
||
|
||
[2](#unique.ptr.single.ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2461)
|
||
|
||
*Preconditions*: D meets the [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [30](utility.arg.requirements#tab:cpp17.defaultconstructible "Table 30: Cpp17DefaultConstructible requirements")),
|
||
and that construction does not throw an exception[.](#unique.ptr.single.ctor-2.sentence-1)
|
||
|
||
[3](#unique.ptr.single.ctor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2466)
|
||
|
||
*Effects*: Constructs a unique_ptr object that owns
|
||
nothing, value-initializing the stored pointer and the stored deleter[.](#unique.ptr.single.ctor-3.sentence-1)
|
||
|
||
[4](#unique.ptr.single.ctor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2471)
|
||
|
||
*Postconditions*: get() == nullptr[.](#unique.ptr.single.ctor-4.sentence-1)
|
||
|
||
get_deleter() returns a reference to the stored deleter[.](#unique.ptr.single.ctor-4.sentence-2)
|
||
|
||
[ð](#lib:unique_ptr,constructor_)
|
||
|
||
`constexpr explicit unique_ptr(type_identity_t<pointer> p) noexcept;
|
||
`
|
||
|
||
[5](#unique.ptr.single.ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2483)
|
||
|
||
*Constraints*: is_pointer_v<deleter_type> is false andis_default_constructible_v<deleter_type> is true[.](#unique.ptr.single.ctor-5.sentence-1)
|
||
|
||
[6](#unique.ptr.single.ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2488)
|
||
|
||
*Preconditions*: D meets the [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [30](utility.arg.requirements#tab:cpp17.defaultconstructible "Table 30: Cpp17DefaultConstructible requirements")),
|
||
and that construction does not throw an exception[.](#unique.ptr.single.ctor-6.sentence-1)
|
||
|
||
[7](#unique.ptr.single.ctor-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2493)
|
||
|
||
*Effects*: Constructs a unique_ptr which ownsp, initializing the stored pointer with p and
|
||
value-initializing the stored deleter[.](#unique.ptr.single.ctor-7.sentence-1)
|
||
|
||
[8](#unique.ptr.single.ctor-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2499)
|
||
|
||
*Postconditions*: get() == p[.](#unique.ptr.single.ctor-8.sentence-1)
|
||
|
||
get_deleter() returns a reference to the stored deleter[.](#unique.ptr.single.ctor-8.sentence-2)
|
||
|
||
[ð](#lib:unique_ptr,constructor__)
|
||
|
||
`constexpr unique_ptr(type_identity_t<pointer> p, const D& d) noexcept;
|
||
constexpr unique_ptr(type_identity_t<pointer> p, remove_reference_t<D>&& d) noexcept;
|
||
`
|
||
|
||
[9](#unique.ptr.single.ctor-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2512)
|
||
|
||
*Constraints*: is_constructible_v<D, decltype(d)> is true[.](#unique.ptr.single.ctor-9.sentence-1)
|
||
|
||
[10](#unique.ptr.single.ctor-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2516)
|
||
|
||
*Preconditions*: For the first constructor, if D is not a reference type,D meets the [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements and
|
||
such construction does not exit via an exception[.](#unique.ptr.single.ctor-10.sentence-1)
|
||
|
||
For the second constructor, if D is not a reference type,D meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements and
|
||
such construction does not exit via an exception[.](#unique.ptr.single.ctor-10.sentence-2)
|
||
|
||
[11](#unique.ptr.single.ctor-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2525)
|
||
|
||
*Effects*: Constructs a unique_ptr object which owns p, initializing
|
||
the stored pointer with p and initializing the deleter
|
||
from std::forward<decltype(d)>(d)[.](#unique.ptr.single.ctor-11.sentence-1)
|
||
|
||
[12](#unique.ptr.single.ctor-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2531)
|
||
|
||
*Postconditions*: get() == p[.](#unique.ptr.single.ctor-12.sentence-1)
|
||
|
||
get_deleter() returns a reference to the stored
|
||
deleter[.](#unique.ptr.single.ctor-12.sentence-2)
|
||
|
||
If D is a reference type then get_deleter() returns a reference to the lvalue d[.](#unique.ptr.single.ctor-12.sentence-3)
|
||
|
||
[13](#unique.ptr.single.ctor-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2538)
|
||
|
||
*Remarks*: If D is a reference type,
|
||
the second constructor is defined as deleted[.](#unique.ptr.single.ctor-13.sentence-1)
|
||
|
||
[14](#unique.ptr.single.ctor-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2543)
|
||
|
||
[*Example [1](#unique.ptr.single.ctor-example-1)*: D d;
|
||
unique_ptr<int, D> p1(new int, D()); // D must be [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") unique_ptr<int, D> p2(new int, d); // D must be [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") unique_ptr<int, D&> p3(new int, d); // p3 holds a reference to d unique_ptr<int, const D&> p4(new int, D()); // error: rvalue deleter object combined// with reference deleter type â *end example*]
|
||
|
||
[ð](#lib:unique_ptr,constructor___)
|
||
|
||
`constexpr unique_ptr(unique_ptr&& u) noexcept;
|
||
`
|
||
|
||
[15](#unique.ptr.single.ctor-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2562)
|
||
|
||
*Constraints*: is_move_constructible_v<D> is true[.](#unique.ptr.single.ctor-15.sentence-1)
|
||
|
||
[16](#unique.ptr.single.ctor-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2566)
|
||
|
||
*Preconditions*: If D is not a reference type,D meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [31](utility.arg.requirements#tab:cpp17.moveconstructible "Table 31: Cpp17MoveConstructible requirements"))[.](#unique.ptr.single.ctor-16.sentence-1)
|
||
|
||
Construction
|
||
of the deleter from an rvalue of type D does not
|
||
throw an exception[.](#unique.ptr.single.ctor-16.sentence-2)
|
||
|
||
[17](#unique.ptr.single.ctor-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2575)
|
||
|
||
*Effects*: Constructs a unique_ptr fromu[.](#unique.ptr.single.ctor-17.sentence-1)
|
||
|
||
If D is a reference type, this
|
||
deleter is copy constructed from u's deleter; otherwise, this
|
||
deleter is move constructed from u's deleter[.](#unique.ptr.single.ctor-17.sentence-2)
|
||
|
||
[*Note [1](#unique.ptr.single.ctor-note-1)*:
|
||
|
||
The
|
||
construction of the deleter can be implemented with std::forward<D>[.](#unique.ptr.single.ctor-17.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[18](#unique.ptr.single.ctor-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2586)
|
||
|
||
*Postconditions*: get() yields the value u.get() yielded before the construction[.](#unique.ptr.single.ctor-18.sentence-1)
|
||
|
||
u.get() == nullptr[.](#unique.ptr.single.ctor-18.sentence-2)
|
||
|
||
get_deleter() returns a reference
|
||
to the stored deleter that was constructed fromu.get_deleter()[.](#unique.ptr.single.ctor-18.sentence-3)
|
||
|
||
If D is a reference type thenget_deleter() and u.get_deleter() both reference
|
||
the same lvalue deleter[.](#unique.ptr.single.ctor-18.sentence-4)
|
||
|
||
[ð](#lib:unique_ptr,constructor____)
|
||
|
||
`template<class U, class E> constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
|
||
`
|
||
|
||
[19](#unique.ptr.single.ctor-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2603)
|
||
|
||
*Constraints*:
|
||
|
||
- [(19.1)](#unique.ptr.single.ctor-19.1)
|
||
|
||
unique_ptr<U, E>::pointer is implicitly convertible to pointer,
|
||
|
||
- [(19.2)](#unique.ptr.single.ctor-19.2)
|
||
|
||
U is not an array type, and
|
||
|
||
- [(19.3)](#unique.ptr.single.ctor-19.3)
|
||
|
||
either D is a reference type and E is the same type as D, orD is not a reference type and E is implicitly convertible to D[.](#unique.ptr.single.ctor-19.sentence-1)
|
||
|
||
[20](#unique.ptr.single.ctor-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2612)
|
||
|
||
*Preconditions*: If E is not a reference type,
|
||
construction of the deleter from an rvalue of type E is well-formed and does not throw an exception[.](#unique.ptr.single.ctor-20.sentence-1)
|
||
|
||
Otherwise, E is a reference type and
|
||
construction of the deleter from an lvalue of type E is well-formed and does not throw an exception[.](#unique.ptr.single.ctor-20.sentence-2)
|
||
|
||
[21](#unique.ptr.single.ctor-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2621)
|
||
|
||
*Effects*: Constructs a unique_ptr from u[.](#unique.ptr.single.ctor-21.sentence-1)
|
||
|
||
If E is a reference type, this deleter is copy constructed fromu's deleter; otherwise, this deleter is move constructed from u's
|
||
deleter[.](#unique.ptr.single.ctor-21.sentence-2)
|
||
|
||
[*Note [2](#unique.ptr.single.ctor-note-2)*:
|
||
|
||
The deleter constructor can be implemented withstd::forward<E>[.](#unique.ptr.single.ctor-21.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[22](#unique.ptr.single.ctor-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2632)
|
||
|
||
*Postconditions*: get() yields the value u.get() yielded before the construction[.](#unique.ptr.single.ctor-22.sentence-1)
|
||
|
||
u.get() == nullptr[.](#unique.ptr.single.ctor-22.sentence-2)
|
||
|
||
get_deleter() returns a reference
|
||
to the stored deleter that was constructed fromu.get_deleter()[.](#unique.ptr.single.ctor-22.sentence-3)
|
||
|
||
#### [20.3.1.3.3](#unique.ptr.single.dtor) Destructor [[unique.ptr.single.dtor]](unique.ptr.single.dtor)
|
||
|
||
[ð](#lib:unique_ptr,destructor)
|
||
|
||
`constexpr ~unique_ptr();
|
||
`
|
||
|
||
[1](#unique.ptr.single.dtor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2649)
|
||
|
||
*Effects*: Equivalent to:if (get()) get_deleter()(get());
|
||
|
||
[*Note [1](#unique.ptr.single.dtor-note-1)*:
|
||
|
||
The use of default_delete requires T to be a complete type[.](#unique.ptr.single.dtor-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#unique.ptr.single.dtor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2657)
|
||
|
||
*Remarks*: The behavior is undefined
|
||
if the evaluation of get_deleter()(get()) throws an exception[.](#unique.ptr.single.dtor-2.sentence-1)
|
||
|
||
#### [20.3.1.3.4](#unique.ptr.single.asgn) Assignment [[unique.ptr.single.asgn]](unique.ptr.single.asgn)
|
||
|
||
[ð](#lib:operator=,unique_ptr)
|
||
|
||
`constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;
|
||
`
|
||
|
||
[1](#unique.ptr.single.asgn-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2671)
|
||
|
||
*Constraints*: is_move_assignable_v<D> is true[.](#unique.ptr.single.asgn-1.sentence-1)
|
||
|
||
[2](#unique.ptr.single.asgn-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2675)
|
||
|
||
*Preconditions*: If D is not a reference type, D meets the[*Cpp17MoveAssignable*](utility.arg.requirements#:Cpp17MoveAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [33](utility.arg.requirements#tab:cpp17.moveassignable "Table 33: Cpp17MoveAssignable requirements")) and assignment
|
||
of the deleter from an rvalue of type D does not throw an exception[.](#unique.ptr.single.asgn-2.sentence-1)
|
||
|
||
Otherwise, D is a reference type;remove_reference_t<D> meets the [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements and assignment of the deleter from an
|
||
lvalue of type D does not throw an exception[.](#unique.ptr.single.asgn-2.sentence-2)
|
||
|
||
[3](#unique.ptr.single.asgn-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2685)
|
||
|
||
*Effects*: Calls reset(u.release()) followed byget_deleter() = std::forward<D>(u.get_deleter())[.](#unique.ptr.single.asgn-3.sentence-1)
|
||
|
||
[4](#unique.ptr.single.asgn-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2690)
|
||
|
||
*Postconditions*: If this != addressof(u),u.get() == nullptr,
|
||
otherwise u.get() is unchanged[.](#unique.ptr.single.asgn-4.sentence-1)
|
||
|
||
[5](#unique.ptr.single.asgn-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2696)
|
||
|
||
*Returns*: *this[.](#unique.ptr.single.asgn-5.sentence-1)
|
||
|
||
[ð](#lib:operator=,unique_ptr_)
|
||
|
||
`template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
|
||
`
|
||
|
||
[6](#unique.ptr.single.asgn-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2707)
|
||
|
||
*Constraints*:
|
||
|
||
- [(6.1)](#unique.ptr.single.asgn-6.1)
|
||
|
||
unique_ptr<U, E>::pointer is implicitly convertible to pointer, and
|
||
|
||
- [(6.2)](#unique.ptr.single.asgn-6.2)
|
||
|
||
U is not an array type, and
|
||
|
||
- [(6.3)](#unique.ptr.single.asgn-6.3)
|
||
|
||
is_assignable_v<D&, E&&> is true[.](#unique.ptr.single.asgn-6.sentence-1)
|
||
|
||
[7](#unique.ptr.single.asgn-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2715)
|
||
|
||
*Preconditions*: If E is not a reference type,
|
||
assignment of the deleter from an rvalue of type E is well-formed and does not throw an exception[.](#unique.ptr.single.asgn-7.sentence-1)
|
||
|
||
Otherwise, E is a reference type and
|
||
assignment of the deleter from an lvalue of type E is well-formed and does not throw an exception[.](#unique.ptr.single.asgn-7.sentence-2)
|
||
|
||
[8](#unique.ptr.single.asgn-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2724)
|
||
|
||
*Effects*: Calls reset(u.release()) followed byget_deleter() = std::forward<E>(u.get_deleter())[.](#unique.ptr.single.asgn-8.sentence-1)
|
||
|
||
[9](#unique.ptr.single.asgn-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2729)
|
||
|
||
*Postconditions*: u.get() == nullptr[.](#unique.ptr.single.asgn-9.sentence-1)
|
||
|
||
[10](#unique.ptr.single.asgn-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2733)
|
||
|
||
*Returns*: *this[.](#unique.ptr.single.asgn-10.sentence-1)
|
||
|
||
[ð](#lib:operator=,unique_ptr__)
|
||
|
||
`constexpr unique_ptr& operator=(nullptr_t) noexcept;
|
||
`
|
||
|
||
[11](#unique.ptr.single.asgn-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2744)
|
||
|
||
*Effects*: As if by reset()[.](#unique.ptr.single.asgn-11.sentence-1)
|
||
|
||
[12](#unique.ptr.single.asgn-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2748)
|
||
|
||
*Postconditions*: get() == nullptr[.](#unique.ptr.single.asgn-12.sentence-1)
|
||
|
||
[13](#unique.ptr.single.asgn-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2752)
|
||
|
||
*Returns*: *this[.](#unique.ptr.single.asgn-13.sentence-1)
|
||
|
||
#### [20.3.1.3.5](#unique.ptr.single.observers) Observers [[unique.ptr.single.observers]](unique.ptr.single.observers)
|
||
|
||
[ð](#lib:operator*,unique_ptr)
|
||
|
||
`constexpr add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));
|
||
`
|
||
|
||
[1](#unique.ptr.single.observers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2765)
|
||
|
||
*Mandates*: reference_converts_from_temporary_v<add_lvalue_reference_t<T>, decltype(
|
||
*declval<pointer>())> is false[.](#unique.ptr.single.observers-1.sentence-1)
|
||
|
||
[2](#unique.ptr.single.observers-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2769)
|
||
|
||
*Preconditions*: get() != nullptr is true[.](#unique.ptr.single.observers-2.sentence-1)
|
||
|
||
[3](#unique.ptr.single.observers-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2773)
|
||
|
||
*Returns*: *get()[.](#unique.ptr.single.observers-3.sentence-1)
|
||
|
||
[ð](#lib:operator-%3e,unique_ptr)
|
||
|
||
`constexpr pointer operator->() const noexcept;
|
||
`
|
||
|
||
[4](#unique.ptr.single.observers-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2785)
|
||
|
||
*Preconditions*: get() != nullptr[.](#unique.ptr.single.observers-4.sentence-1)
|
||
|
||
[5](#unique.ptr.single.observers-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2789)
|
||
|
||
*Returns*: get()[.](#unique.ptr.single.observers-5.sentence-1)
|
||
|
||
[6](#unique.ptr.single.observers-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2793)
|
||
|
||
[*Note [1](#unique.ptr.single.observers-note-1)*:
|
||
|
||
The use of this function typically requires that T be a complete type[.](#unique.ptr.single.observers-6.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:get,unique_ptr)
|
||
|
||
`constexpr pointer get() const noexcept;
|
||
`
|
||
|
||
[7](#unique.ptr.single.observers-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2805)
|
||
|
||
*Returns*: The stored pointer[.](#unique.ptr.single.observers-7.sentence-1)
|
||
|
||
[ð](#lib:get_deleter,unique_ptr)
|
||
|
||
`constexpr deleter_type& get_deleter() noexcept;
|
||
constexpr const deleter_type& get_deleter() const noexcept;
|
||
`
|
||
|
||
[8](#unique.ptr.single.observers-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2817)
|
||
|
||
*Returns*: A reference to the stored deleter[.](#unique.ptr.single.observers-8.sentence-1)
|
||
|
||
[ð](#lib:operator_bool,unique_ptr)
|
||
|
||
`constexpr explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[9](#unique.ptr.single.observers-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2828)
|
||
|
||
*Returns*: get() != nullptr[.](#unique.ptr.single.observers-9.sentence-1)
|
||
|
||
#### [20.3.1.3.6](#unique.ptr.single.modifiers) Modifiers [[unique.ptr.single.modifiers]](unique.ptr.single.modifiers)
|
||
|
||
[ð](#lib:release,unique_ptr)
|
||
|
||
`constexpr pointer release() noexcept;
|
||
`
|
||
|
||
[1](#unique.ptr.single.modifiers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2841)
|
||
|
||
*Postconditions*: get() == nullptr[.](#unique.ptr.single.modifiers-1.sentence-1)
|
||
|
||
[2](#unique.ptr.single.modifiers-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2845)
|
||
|
||
*Returns*: The value get() had at the start of
|
||
the call to release[.](#unique.ptr.single.modifiers-2.sentence-1)
|
||
|
||
[ð](#lib:reset,unique_ptr)
|
||
|
||
`constexpr void reset(pointer p = pointer()) noexcept;
|
||
`
|
||
|
||
[3](#unique.ptr.single.modifiers-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2857)
|
||
|
||
*Effects*: Assigns p to the stored pointer, and then,
|
||
with the old value of the stored pointer, old_p,
|
||
evaluates if (old_p) get_deleter()(old_p);
|
||
|
||
[*Note [1](#unique.ptr.single.modifiers-note-1)*:
|
||
|
||
The order of these operations is significant
|
||
because the call to get_deleter() might destroy *this[.](#unique.ptr.single.modifiers-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[4](#unique.ptr.single.modifiers-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2867)
|
||
|
||
*Postconditions*: get() == p[.](#unique.ptr.single.modifiers-4.sentence-1)
|
||
|
||
[*Note [2](#unique.ptr.single.modifiers-note-2)*:
|
||
|
||
The postcondition does not hold if the call to get_deleter() destroys *this since this->get() is no longer a valid expression[.](#unique.ptr.single.modifiers-4.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[5](#unique.ptr.single.modifiers-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2875)
|
||
|
||
*Remarks*: The behavior is undefined
|
||
if the evaluation of get_deleter()(old_p) throws an exception[.](#unique.ptr.single.modifiers-5.sentence-1)
|
||
|
||
[ð](#lib:swap,unique_ptr)
|
||
|
||
`constexpr void swap(unique_ptr& u) noexcept;
|
||
`
|
||
|
||
[6](#unique.ptr.single.modifiers-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2887)
|
||
|
||
*Preconditions*: get_deleter() is swappable ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements")) and
|
||
does not throw an exception under swap[.](#unique.ptr.single.modifiers-6.sentence-1)
|
||
|
||
[7](#unique.ptr.single.modifiers-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2892)
|
||
|
||
*Effects*: Invokes swap on the stored pointers and on the stored
|
||
deleters of *this and u[.](#unique.ptr.single.modifiers-7.sentence-1)
|
||
|
||
#### [20.3.1.4](#unique.ptr.runtime) unique_ptr for array objects with a runtime length [[unique.ptr.runtime]](unique.ptr.runtime)
|
||
|
||
#### [20.3.1.4.1](#unique.ptr.runtime.general) General [[unique.ptr.runtime.general]](unique.ptr.runtime.general)
|
||
|
||
[ð](#lib:unique_ptr_)
|
||
|
||
namespace std {template<class T, class D> class unique_ptr<T[], D> {public:using pointer = *see below*; using element_type = T; using deleter_type = D; // [[unique.ptr.runtime.ctor]](#unique.ptr.runtime.ctor "20.3.1.4.2 Constructors"), constructorsconstexpr unique_ptr() noexcept; template<class U> constexpr explicit unique_ptr(U p) noexcept; template<class U> constexpr unique_ptr(U p, *see below* d) noexcept; template<class U> constexpr unique_ptr(U p, *see below* d) noexcept; constexpr unique_ptr(unique_ptr&& u) noexcept; template<class U, class E>constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; // destructorconstexpr ~unique_ptr(); // assignmentconstexpr unique_ptr& operator=(unique_ptr&& u) noexcept; template<class U, class E>constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; constexpr unique_ptr& operator=(nullptr_t) noexcept; // [[unique.ptr.runtime.observers]](#unique.ptr.runtime.observers "20.3.1.4.4 Observers"), observersconstexpr T& operator[](size_t i) const; constexpr pointer get() const noexcept; constexpr deleter_type& get_deleter() noexcept; constexpr const deleter_type& get_deleter() const noexcept; constexpr explicit operator bool() const noexcept; // [[unique.ptr.runtime.modifiers]](#unique.ptr.runtime.modifiers "20.3.1.4.5 Modifiers"), modifiersconstexpr pointer release() noexcept; template<class U> constexpr void reset(U p) noexcept; constexpr void reset(nullptr_t = nullptr) noexcept; constexpr void swap(unique_ptr& u) noexcept; // disable copy from lvalue unique_ptr(const unique_ptr&) = delete;
|
||
unique_ptr& operator=(const unique_ptr&) = delete; };}
|
||
|
||
[1](#unique.ptr.runtime.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2950)
|
||
|
||
A specialization for array types is provided with a slightly altered
|
||
interface[.](#unique.ptr.runtime.general-1.sentence-1)
|
||
|
||
- [(1.1)](#unique.ptr.runtime.general-1.1)
|
||
|
||
Conversions between different types ofunique_ptr<T[], D> that would be disallowed for the corresponding pointer-to-array types,
|
||
and conversions to or from the non-array forms ofunique_ptr, produce an ill-formed program[.](#unique.ptr.runtime.general-1.1.sentence-1)
|
||
|
||
- [(1.2)](#unique.ptr.runtime.general-1.2)
|
||
|
||
Pointers to types derived from T are
|
||
rejected by the constructors, and by reset[.](#unique.ptr.runtime.general-1.2.sentence-1)
|
||
|
||
- [(1.3)](#unique.ptr.runtime.general-1.3)
|
||
|
||
The observers operator* andoperator-> are not provided[.](#unique.ptr.runtime.general-1.3.sentence-1)
|
||
|
||
- [(1.4)](#unique.ptr.runtime.general-1.4)
|
||
|
||
The indexing observer operator[] is provided[.](#unique.ptr.runtime.general-1.4.sentence-1)
|
||
|
||
- [(1.5)](#unique.ptr.runtime.general-1.5)
|
||
|
||
The default deleter will call delete[][.](#unique.ptr.runtime.general-1.5.sentence-1)
|
||
|
||
[2](#unique.ptr.runtime.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2972)
|
||
|
||
Descriptions are provided below only for members that
|
||
differ from the primary template[.](#unique.ptr.runtime.general-2.sentence-1)
|
||
|
||
[3](#unique.ptr.runtime.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2976)
|
||
|
||
The template argument T shall be a complete type[.](#unique.ptr.runtime.general-3.sentence-1)
|
||
|
||
#### [20.3.1.4.2](#unique.ptr.runtime.ctor) Constructors [[unique.ptr.runtime.ctor]](unique.ptr.runtime.ctor)
|
||
|
||
[ð](#lib:unique_ptr,constructor_____)
|
||
|
||
`template<class U> constexpr explicit unique_ptr(U p) noexcept;
|
||
`
|
||
|
||
[1](#unique.ptr.runtime.ctor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2987)
|
||
|
||
This constructor behaves the same as
|
||
the constructor in the primary template that
|
||
takes a single parameter of type pointer[.](#unique.ptr.runtime.ctor-1.sentence-1)
|
||
|
||
[2](#unique.ptr.runtime.ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2992)
|
||
|
||
*Constraints*:
|
||
|
||
- [(2.1)](#unique.ptr.runtime.ctor-2.1)
|
||
|
||
U is the same type as pointer, or
|
||
|
||
- [(2.2)](#unique.ptr.runtime.ctor-2.2)
|
||
|
||
pointer is the same type as element_type*,U is a pointer type V*, andV(*)[] is convertible to element_type(*)[][.](#unique.ptr.runtime.ctor-2.sentence-1)
|
||
|
||
[ð](#lib:unique_ptr,constructor______)
|
||
|
||
`template<class U> constexpr unique_ptr(U p, see below d) noexcept;
|
||
template<class U> constexpr unique_ptr(U p, see below d) noexcept;
|
||
`
|
||
|
||
[3](#unique.ptr.runtime.ctor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3009)
|
||
|
||
These constructors behave the same as
|
||
the constructors in the primary template that
|
||
take a parameter of type pointer and a second parameter[.](#unique.ptr.runtime.ctor-3.sentence-1)
|
||
|
||
[4](#unique.ptr.runtime.ctor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3014)
|
||
|
||
*Constraints*:
|
||
|
||
- [(4.1)](#unique.ptr.runtime.ctor-4.1)
|
||
|
||
U is the same type as pointer,
|
||
|
||
- [(4.2)](#unique.ptr.runtime.ctor-4.2)
|
||
|
||
U is nullptr_t, or
|
||
|
||
- [(4.3)](#unique.ptr.runtime.ctor-4.3)
|
||
|
||
pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[][.](#unique.ptr.runtime.ctor-4.sentence-1)
|
||
|
||
[ð](#lib:unique_ptr,constructor_______)
|
||
|
||
`template<class U, class E> constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;
|
||
`
|
||
|
||
[5](#unique.ptr.runtime.ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3031)
|
||
|
||
This constructor behaves the same as in the primary template[.](#unique.ptr.runtime.ctor-5.sentence-1)
|
||
|
||
[6](#unique.ptr.runtime.ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3034)
|
||
|
||
*Constraints*: Where UP is unique_ptr<U, E>:
|
||
|
||
- [(6.1)](#unique.ptr.runtime.ctor-6.1)
|
||
|
||
U is an array type, and
|
||
|
||
- [(6.2)](#unique.ptr.runtime.ctor-6.2)
|
||
|
||
pointer is the same type as element_type*, and
|
||
|
||
- [(6.3)](#unique.ptr.runtime.ctor-6.3)
|
||
|
||
UP::pointer is the same type as UP::element_type*, and
|
||
|
||
- [(6.4)](#unique.ptr.runtime.ctor-6.4)
|
||
|
||
UP::element_type(*)[] is convertible to element_type(*)[], and
|
||
|
||
- [(6.5)](#unique.ptr.runtime.ctor-6.5)
|
||
|
||
either D is a reference type and E is the same type as D,
|
||
or D is not a reference type and E is implicitly convertible to D[.](#unique.ptr.runtime.ctor-6.sentence-1)
|
||
|
||
[*Note [1](#unique.ptr.runtime.ctor-note-1)*:
|
||
|
||
This replaces the *Constraints*: specification of the primary template[.](#unique.ptr.runtime.ctor-6.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.1.4.3](#unique.ptr.runtime.asgn) Assignment [[unique.ptr.runtime.asgn]](unique.ptr.runtime.asgn)
|
||
|
||
[ð](#lib:operator=,unique_ptr___)
|
||
|
||
`template<class U, class E> constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
|
||
`
|
||
|
||
[1](#unique.ptr.runtime.asgn-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3059)
|
||
|
||
This operator behaves the same as in the primary template[.](#unique.ptr.runtime.asgn-1.sentence-1)
|
||
|
||
[2](#unique.ptr.runtime.asgn-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3062)
|
||
|
||
*Constraints*: Where UP is unique_ptr<U, E>:
|
||
|
||
- [(2.1)](#unique.ptr.runtime.asgn-2.1)
|
||
|
||
U is an array type, and
|
||
|
||
- [(2.2)](#unique.ptr.runtime.asgn-2.2)
|
||
|
||
pointer is the same type as element_type*, and
|
||
|
||
- [(2.3)](#unique.ptr.runtime.asgn-2.3)
|
||
|
||
UP::pointer is the same type as UP::element_type*, and
|
||
|
||
- [(2.4)](#unique.ptr.runtime.asgn-2.4)
|
||
|
||
UP::element_type(*)[] is convertible to element_type(*)[], and
|
||
|
||
- [(2.5)](#unique.ptr.runtime.asgn-2.5)
|
||
|
||
is_assignable_v<D&, E&&> is true[.](#unique.ptr.runtime.asgn-2.sentence-1)
|
||
|
||
[*Note [1](#unique.ptr.runtime.asgn-note-1)*:
|
||
|
||
This replaces the *Constraints*: specification of the primary template[.](#unique.ptr.runtime.asgn-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.1.4.4](#unique.ptr.runtime.observers) Observers [[unique.ptr.runtime.observers]](unique.ptr.runtime.observers)
|
||
|
||
[ð](#lib:operator%5b%5d,unique_ptr)
|
||
|
||
`constexpr T& operator[](size_t i) const;
|
||
`
|
||
|
||
[1](#unique.ptr.runtime.observers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3086)
|
||
|
||
*Preconditions*: i < the
|
||
number of elements in the array to which
|
||
the stored pointer points[.](#unique.ptr.runtime.observers-1.sentence-1)
|
||
|
||
[2](#unique.ptr.runtime.observers-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3092)
|
||
|
||
*Returns*: get()[i][.](#unique.ptr.runtime.observers-2.sentence-1)
|
||
|
||
#### [20.3.1.4.5](#unique.ptr.runtime.modifiers) Modifiers [[unique.ptr.runtime.modifiers]](unique.ptr.runtime.modifiers)
|
||
|
||
[ð](#lib:reset,unique_ptr_)
|
||
|
||
`constexpr void reset(nullptr_t p = nullptr) noexcept;
|
||
`
|
||
|
||
[1](#unique.ptr.runtime.modifiers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3105)
|
||
|
||
*Effects*: Equivalent to reset(pointer())[.](#unique.ptr.runtime.modifiers-1.sentence-1)
|
||
|
||
[ð](#lib:reset,unique_ptr__)
|
||
|
||
`template<class U> constexpr void reset(U p) noexcept;
|
||
`
|
||
|
||
[2](#unique.ptr.runtime.modifiers-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3116)
|
||
|
||
This function behaves the same as
|
||
the reset member of the primary template[.](#unique.ptr.runtime.modifiers-2.sentence-1)
|
||
|
||
[3](#unique.ptr.runtime.modifiers-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3120)
|
||
|
||
*Constraints*:
|
||
|
||
- [(3.1)](#unique.ptr.runtime.modifiers-3.1)
|
||
|
||
U is the same type as pointer, or
|
||
|
||
- [(3.2)](#unique.ptr.runtime.modifiers-3.2)
|
||
|
||
pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[][.](#unique.ptr.runtime.modifiers-3.sentence-1)
|
||
|
||
#### [20.3.1.5](#unique.ptr.create) Creation [[unique.ptr.create]](unique.ptr.create)
|
||
|
||
[ð](#lib:make_unique)
|
||
|
||
`template<class T, class... Args> constexpr unique_ptr<T> make_unique(Args&&... args);
|
||
`
|
||
|
||
[1](#unique.ptr.create-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3138)
|
||
|
||
*Constraints*: T is not an array type[.](#unique.ptr.create-1.sentence-1)
|
||
|
||
[2](#unique.ptr.create-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3142)
|
||
|
||
*Returns*: unique_ptr<T>(new T(std::forward<Args>(args)...))[.](#unique.ptr.create-2.sentence-1)
|
||
|
||
[ð](#lib:make_unique_)
|
||
|
||
`template<class T> constexpr unique_ptr<T> make_unique(size_t n);
|
||
`
|
||
|
||
[3](#unique.ptr.create-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3154)
|
||
|
||
*Constraints*: T is an array of unknown bound[.](#unique.ptr.create-3.sentence-1)
|
||
|
||
[4](#unique.ptr.create-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3158)
|
||
|
||
*Returns*: unique_ptr<T>(new remove_extent_t<T>[n]())[.](#unique.ptr.create-4.sentence-1)
|
||
|
||
[ð](#lib:make_unique__)
|
||
|
||
`template<class T, class... Args> unspecified make_unique(Args&&...) = delete;
|
||
`
|
||
|
||
[5](#unique.ptr.create-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3170)
|
||
|
||
*Constraints*: T is an array of known bound[.](#unique.ptr.create-5.sentence-1)
|
||
|
||
[ð](#lib:make_unique___)
|
||
|
||
`template<class T> constexpr unique_ptr<T> make_unique_for_overwrite();
|
||
`
|
||
|
||
[6](#unique.ptr.create-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3182)
|
||
|
||
*Constraints*: T is not an array type[.](#unique.ptr.create-6.sentence-1)
|
||
|
||
[7](#unique.ptr.create-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3186)
|
||
|
||
*Returns*: unique_ptr<T>(new T)[.](#unique.ptr.create-7.sentence-1)
|
||
|
||
[ð](#lib:make_unique____)
|
||
|
||
`template<class T> constexpr unique_ptr<T> make_unique_for_overwrite(size_t n);
|
||
`
|
||
|
||
[8](#unique.ptr.create-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3197)
|
||
|
||
*Constraints*: T is an array of unknown bound[.](#unique.ptr.create-8.sentence-1)
|
||
|
||
[9](#unique.ptr.create-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3201)
|
||
|
||
*Returns*: unique_ptr<T>(new remove_extent_t<T>[n])[.](#unique.ptr.create-9.sentence-1)
|
||
|
||
[ð](#lib:make_unique_____)
|
||
|
||
`template<class T, class... Args> unspecified make_unique_for_overwrite(Args&&...) = delete;
|
||
`
|
||
|
||
[10](#unique.ptr.create-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3212)
|
||
|
||
*Constraints*: T is an array of known bound[.](#unique.ptr.create-10.sentence-1)
|
||
|
||
#### [20.3.1.6](#unique.ptr.special) Specialized algorithms [[unique.ptr.special]](unique.ptr.special)
|
||
|
||
[ð](#lib:swap(unique_ptr&,_unique_ptr&))
|
||
|
||
`template<class T, class D> constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
|
||
`
|
||
|
||
[1](#unique.ptr.special-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3225)
|
||
|
||
*Constraints*: is_swappable_v<D> is true[.](#unique.ptr.special-1.sentence-1)
|
||
|
||
[2](#unique.ptr.special-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3229)
|
||
|
||
*Effects*: Calls x.swap(y)[.](#unique.ptr.special-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,unique_ptr)
|
||
|
||
`template<class T1, class D1, class T2, class D2>
|
||
constexpr bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
|
||
`
|
||
|
||
[3](#unique.ptr.special-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3241)
|
||
|
||
*Returns*: x.get() == y.get()[.](#unique.ptr.special-3.sentence-1)
|
||
|
||
[ð](#lib:operator%3c,unique_ptr)
|
||
|
||
`template<class T1, class D1, class T2, class D2>
|
||
constexpr bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
|
||
`
|
||
|
||
[4](#unique.ptr.special-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3253)
|
||
|
||
Let CT denotecommon_type_t<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer>
|
||
|
||
[5](#unique.ptr.special-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3260)
|
||
|
||
*Mandates*:
|
||
|
||
- [(5.1)](#unique.ptr.special-5.1)
|
||
|
||
unique_ptr<T1, D1>::pointer is implicitly convertible to CT and
|
||
|
||
- [(5.2)](#unique.ptr.special-5.2)
|
||
|
||
unique_ptr<T2, D2>::pointer is implicitly convertible to CT[.](#unique.ptr.special-5.sentence-1)
|
||
|
||
[6](#unique.ptr.special-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3267)
|
||
|
||
*Preconditions*: The specializationless<CT> is a function object type ([[function.objects]](function.objects "22.10 Function objects")) that
|
||
induces a strict weak ordering ([[alg.sorting]](alg.sorting "26.8 Sorting and related operations")) on the pointer values[.](#unique.ptr.special-6.sentence-1)
|
||
|
||
[7](#unique.ptr.special-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3273)
|
||
|
||
*Returns*: less<CT>()(x.get(), y.get())[.](#unique.ptr.special-7.sentence-1)
|
||
|
||
[ð](#lib:operator%3e,unique_ptr)
|
||
|
||
`template<class T1, class D1, class T2, class D2>
|
||
constexpr bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
|
||
`
|
||
|
||
[8](#unique.ptr.special-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3285)
|
||
|
||
*Returns*: y < x[.](#unique.ptr.special-8.sentence-1)
|
||
|
||
[ð](#lib:operator%3c=,unique_ptr)
|
||
|
||
`template<class T1, class D1, class T2, class D2>
|
||
constexpr bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
|
||
`
|
||
|
||
[9](#unique.ptr.special-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3297)
|
||
|
||
*Returns*: !(y < x)[.](#unique.ptr.special-9.sentence-1)
|
||
|
||
[ð](#lib:operator%3e=,unique_ptr)
|
||
|
||
`template<class T1, class D1, class T2, class D2>
|
||
constexpr bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
|
||
`
|
||
|
||
[10](#unique.ptr.special-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3309)
|
||
|
||
*Returns*: !(x < y)[.](#unique.ptr.special-10.sentence-1)
|
||
|
||
[ð](#lib:operator%3c=%3e,unique_ptr)
|
||
|
||
`template<class T1, class D1, class T2, class D2>
|
||
requires [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept three_way_comparable [cmp.concept]")<typename unique_ptr<T1, D1>::pointer,
|
||
typename unique_ptr<T2, D2>::pointer>
|
||
constexpr compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
|
||
typename unique_ptr<T2, D2>::pointer>
|
||
operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
|
||
`
|
||
|
||
[11](#unique.ptr.special-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3325)
|
||
|
||
*Returns*: compare_three_way()(x.get(), y.get())[.](#unique.ptr.special-11.sentence-1)
|
||
|
||
[ð](#lib:operator==,unique_ptr_)
|
||
|
||
`template<class T, class D>
|
||
constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
|
||
`
|
||
|
||
[12](#unique.ptr.special-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3337)
|
||
|
||
*Returns*: !x[.](#unique.ptr.special-12.sentence-1)
|
||
|
||
[ð](#lib:operator%3c,unique_ptr_)
|
||
|
||
`template<class T, class D>
|
||
constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t);
|
||
template<class T, class D>
|
||
constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& x);
|
||
`
|
||
|
||
[13](#unique.ptr.special-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3351)
|
||
|
||
*Preconditions*: The specialization less<unique_ptr<T, D>::pointer> is
|
||
a function object type ([[function.objects]](function.objects "22.10 Function objects")) that induces a strict weak
|
||
ordering ([[alg.sorting]](alg.sorting "26.8 Sorting and related operations")) on the pointer values[.](#unique.ptr.special-13.sentence-1)
|
||
|
||
[14](#unique.ptr.special-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3357)
|
||
|
||
*Returns*: The first function template returnsless<unique_ptr<T, D>::pointer>()(x.get(), nullptr)
|
||
|
||
The second function template returnsless<unique_ptr<T, D>::pointer>()(nullptr, x.get())
|
||
|
||
[ð](#lib:operator%3e,unique_ptr_)
|
||
|
||
`template<class T, class D>
|
||
constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t);
|
||
template<class T, class D>
|
||
constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& x);
|
||
`
|
||
|
||
[15](#unique.ptr.special-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3378)
|
||
|
||
*Returns*: The first function template returns nullptr < x[.](#unique.ptr.special-15.sentence-1)
|
||
|
||
The second function template returns x < nullptr[.](#unique.ptr.special-15.sentence-2)
|
||
|
||
[ð](#lib:operator%3c=,unique_ptr_)
|
||
|
||
`template<class T, class D>
|
||
constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
|
||
template<class T, class D>
|
||
constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& x);
|
||
`
|
||
|
||
[16](#unique.ptr.special-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3393)
|
||
|
||
*Returns*: The first function template returns !(nullptr < x)[.](#unique.ptr.special-16.sentence-1)
|
||
|
||
The second function template returns !(x < nullptr)[.](#unique.ptr.special-16.sentence-2)
|
||
|
||
[ð](#lib:operator%3e=,unique_ptr_)
|
||
|
||
`template<class T, class D>
|
||
constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
|
||
template<class T, class D>
|
||
constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& x);
|
||
`
|
||
|
||
[17](#unique.ptr.special-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3408)
|
||
|
||
*Returns*: The first function template returns !(x < nullptr)[.](#unique.ptr.special-17.sentence-1)
|
||
|
||
The second function template returns !(nullptr < x)[.](#unique.ptr.special-17.sentence-2)
|
||
|
||
[ð](#lib:operator%3c=%3e,unique_ptr_)
|
||
|
||
`template<class T, class D>
|
||
requires [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_way_comparable [cmp.concept]")<typename unique_ptr<T, D>::pointer>
|
||
constexpr compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
|
||
operator<=>(const unique_ptr<T, D>& x, nullptr_t);
|
||
`
|
||
|
||
[18](#unique.ptr.special-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3423)
|
||
|
||
*Returns*: compare_three_way()(x.get(), static_cast<typename unique_ptr<T, D>::pointer>(nullptr)).
|
||
|
||
#### [20.3.1.7](#unique.ptr.io) I/O [[unique.ptr.io]](unique.ptr.io)
|
||
|
||
[ð](#lib:operator%3c%3c,unique_ptr)
|
||
|
||
`template<class E, class T, class Y, class D>
|
||
basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const unique_ptr<Y, D>& p);
|
||
`
|
||
|
||
[1](#unique.ptr.io-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3439)
|
||
|
||
*Constraints*: os << p.get() is a valid expression[.](#unique.ptr.io-1.sentence-1)
|
||
|
||
[2](#unique.ptr.io-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3443)
|
||
|
||
*Effects*: Equivalent to: os << p.get();
|
||
|
||
[3](#unique.ptr.io-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L3447)
|
||
|
||
*Returns*: os[.](#unique.ptr.io-3.sentence-1)
|
||
|
||
### [20.3.2](#util.sharedptr) Shared-ownership pointers [[util.sharedptr]](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],
|
||
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)
|
||
|
||
### [20.3.3](#util.smartptr.hash) Smart pointer hash support [[util.smartptr.hash]](util.smartptr.hash)
|
||
|
||
[ð](#lib:hash,unique_ptr)
|
||
|
||
`template<class T, class D> struct hash<unique_ptr<T, D>>;
|
||
`
|
||
|
||
[1](#util.smartptr.hash-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5396)
|
||
|
||
Letting UP be unique_ptr<T, D>,
|
||
the specialization hash<UP> is enabled ([[unord.hash]](unord.hash "22.10.19 Class template hash"))
|
||
if and only if hash<typename UP::pointer> is enabled[.](#util.smartptr.hash-1.sentence-1)
|
||
|
||
When enabled, for an object p of type UP,hash<UP>()(p) evaluates to
|
||
the same value as hash<typename UP::pointer>()(p.get())[.](#util.smartptr.hash-1.sentence-2)
|
||
|
||
The member functions are not guaranteed to be noexcept[.](#util.smartptr.hash-1.sentence-3)
|
||
|
||
[ð](#lib:hash,shared_ptr)
|
||
|
||
`template<class T> struct hash<shared_ptr<T>>;
|
||
`
|
||
|
||
[2](#util.smartptr.hash-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5412)
|
||
|
||
For an object p of type shared_ptr<T>,hash<shared_ptr<T>>()(p) evaluates to
|
||
the same value as hash<typename shared_ptr<T>::element_type*>()(p.get())[.](#util.smartptr.hash-2.sentence-1)
|
||
|
||
### [20.3.4](#adapt) Smart pointer adaptors [[smartptr.adapt]](smartptr.adapt)
|
||
|
||
#### [20.3.4.1](#out.ptr.t) Class template out_ptr_t [[out.ptr.t]](out.ptr.t)
|
||
|
||
[1](#out.ptr.t-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5423)
|
||
|
||
out_ptr_t is a class template used to adapt types
|
||
such as smart pointers ([smartptr])
|
||
for functions that use output pointer parameters[.](#out.ptr.t-1.sentence-1)
|
||
|
||
[2](#out.ptr.t-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5428)
|
||
|
||
[*Example [1](#out.ptr.t-example-1)*:
|
||
|
||
#include <memory>#include <cstdio>int fopen_s(std::FILE** f, const char* name, const char* mode);
|
||
|
||
struct fclose_deleter {void operator()(std::FILE* f) const noexcept { std::fclose(f); }};
|
||
|
||
int main(int, char*[]) {constexpr const char* file_name = "ow.o";
|
||
std::unique_ptr<std::FILE, fclose_deleter> file_ptr; int err = fopen_s(std::out_ptr<std::FILE*>(file_ptr), file_name, "r+b"); if (err != 0)return 1; // *file_ptr is validreturn 0;}unique_ptr can be used with out_ptr to be passed into an output pointer-style function,
|
||
without needing to hold onto an intermediate pointer value and
|
||
manually delete it on error or failure[.](#out.ptr.t-2.sentence-1)
|
||
|
||
â *end example*]
|
||
|
||
[ð](#lib:out_ptr_t)
|
||
|
||
namespace std {template<class Smart, class Pointer, class... Args>class out_ptr_t {public:constexpr explicit out_ptr_t(Smart&, Args...);
|
||
out_ptr_t(const out_ptr_t&) = delete; constexpr ~out_ptr_t(); constexpr operator Pointer*() const noexcept; operator void**() const noexcept; private: Smart& s; // *exposition only* tuple<Args...> a; // *exposition only* Pointer p; // *exposition only*};}
|
||
|
||
[3](#out.ptr.t-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5480)
|
||
|
||
Pointer shall meet the [*Cpp17NullablePointer*](nullablepointer.requirements#:Cpp17NullablePointer "16.4.4.4 Cpp17NullablePointer requirements [nullablepointer.requirements]") requirements[.](#out.ptr.t-3.sentence-1)
|
||
|
||
If Smart is a specialization of shared_ptr andsizeof...(Args) == 0,
|
||
the program is ill-formed[.](#out.ptr.t-3.sentence-2)
|
||
|
||
[*Note [1](#out.ptr.t-note-1)*:
|
||
|
||
It is typically a user error to reset a shared_ptr without specifying a deleter,
|
||
as shared_ptr will replace a custom deleter upon usage of reset,
|
||
as specified in [[util.smartptr.shared.mod]](#util.smartptr.shared.mod "20.3.2.2.5 Modifiers")[.](#out.ptr.t-3.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[4](#out.ptr.t-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5492)
|
||
|
||
Program-defined specializations of out_ptr_t that depend on at least one program-defined type
|
||
need not meet the requirements for the primary template[.](#out.ptr.t-4.sentence-1)
|
||
|
||
[5](#out.ptr.t-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5497)
|
||
|
||
Evaluations of the conversion functions
|
||
on the same object may conflict ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#out.ptr.t-5.sentence-1)
|
||
|
||
[ð](#lib:out_ptr_t,constructor)
|
||
|
||
`constexpr explicit out_ptr_t(Smart& smart, Args... args);
|
||
`
|
||
|
||
[6](#out.ptr.t-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5507)
|
||
|
||
*Effects*: Initializes s with smart,a with std::forward<Args>(args)..., and
|
||
value-initializes p[.](#out.ptr.t-6.sentence-1)
|
||
|
||
Then, equivalent to:
|
||
|
||
- [(6.1)](#out.ptr.t-6.1)
|
||
|
||
s.reset(); if the expression s.reset() is well-formed;
|
||
|
||
- [(6.2)](#out.ptr.t-6.2)
|
||
|
||
otherwise,s = Smart(); if is_constructible_v<Smart> is true;
|
||
|
||
- [(6.3)](#out.ptr.t-6.3)
|
||
|
||
otherwise, the program is ill-formed[.](#out.ptr.t-6.sentence-2)
|
||
|
||
[7](#out.ptr.t-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5533)
|
||
|
||
[*Note [2](#out.ptr.t-note-2)*:
|
||
|
||
The constructor is not noexcept to allow for a variety of non-terminating and safe implementation strategies[.](#out.ptr.t-7.sentence-1)
|
||
|
||
For example, an implementation can allocate
|
||
a shared_ptr's internal node in the constructor and
|
||
let implementation-defined exceptions escape safely[.](#out.ptr.t-7.sentence-2)
|
||
|
||
The destructor can then move the allocated control block in directly and
|
||
avoid any other exceptions[.](#out.ptr.t-7.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:out_ptr_t,destructor)
|
||
|
||
`constexpr ~out_ptr_t();
|
||
`
|
||
|
||
[8](#out.ptr.t-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5551)
|
||
|
||
Let SP be*POINTER_OF_OR*(Smart, Pointer) ([[memory.general]](memory.general "20.2.1 General"))[.](#out.ptr.t-8.sentence-1)
|
||
|
||
[9](#out.ptr.t-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5555)
|
||
|
||
*Effects*: Equivalent to:
|
||
|
||
- [(9.1)](#out.ptr.t-9.1)
|
||
|
||
if (p) { apply([&](auto&&... args) { s.reset(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));} if the expressions.reset(static_cast<SP>(p), std::forward<Args>(args)...) is well-formed;
|
||
|
||
- [(9.2)](#out.ptr.t-9.2)
|
||
|
||
otherwise,if (p) { apply([&](auto&&... args) { s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));} if is_constructible_v<Smart, SP, Args...> is true;
|
||
|
||
- [(9.3)](#out.ptr.t-9.3)
|
||
|
||
otherwise, the program is ill-formed[.](#out.ptr.t-9.sentence-1)
|
||
|
||
[ð](#out.ptr.t-itemdecl:3)
|
||
|
||
`constexpr operator Pointer*() const noexcept;
|
||
`
|
||
|
||
[10](#out.ptr.t-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5590)
|
||
|
||
*Preconditions*: operator void**() has not been called on *this[.](#out.ptr.t-10.sentence-1)
|
||
|
||
[11](#out.ptr.t-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5594)
|
||
|
||
*Returns*: addressof(const_cast<Pointer&>(p))[.](#out.ptr.t-11.sentence-1)
|
||
|
||
[ð](#out.ptr.t-itemdecl:4)
|
||
|
||
`operator void**() const noexcept;
|
||
`
|
||
|
||
[12](#out.ptr.t-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5604)
|
||
|
||
*Constraints*: is_same_v<Pointer, void*> is false[.](#out.ptr.t-12.sentence-1)
|
||
|
||
[13](#out.ptr.t-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5608)
|
||
|
||
*Mandates*: is_pointer_v<Pointer> is true[.](#out.ptr.t-13.sentence-1)
|
||
|
||
[14](#out.ptr.t-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5612)
|
||
|
||
*Preconditions*: operator Pointer*() has not been called on *this[.](#out.ptr.t-14.sentence-1)
|
||
|
||
[15](#out.ptr.t-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5616)
|
||
|
||
*Returns*: A pointer value v such that:
|
||
|
||
- [(15.1)](#out.ptr.t-15.1)
|
||
|
||
the initial value *v is equivalent to static_cast<void*>(p) and
|
||
|
||
- [(15.2)](#out.ptr.t-15.2)
|
||
|
||
any modification of *v that is not followed by a subsequent modification of *this affects the value of p during the destruction of *this,
|
||
such that static_cast<void*>(p) == *v[.](#out.ptr.t-15.sentence-1)
|
||
|
||
[16](#out.ptr.t-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5629)
|
||
|
||
*Remarks*: Accessing *v outside the lifetime of *this has undefined behavior[.](#out.ptr.t-16.sentence-1)
|
||
|
||
[17](#out.ptr.t-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5634)
|
||
|
||
[*Note [3](#out.ptr.t-note-3)*:
|
||
|
||
reinterpret_cast<void**>(static_cast<Pointer*>(*this)) can be a viable implementation strategy for some implementations[.](#out.ptr.t-17.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.4.2](#out.ptr) Function template out_ptr [[out.ptr]](out.ptr)
|
||
|
||
[ð](#lib:out_ptr)
|
||
|
||
`template<class Pointer = void, class Smart, class... Args>
|
||
constexpr auto out_ptr(Smart& s, Args&&... args);
|
||
`
|
||
|
||
[1](#out.ptr-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5650)
|
||
|
||
Let P be Pointer if is_void_v<Pointer> is false,
|
||
otherwise *POINTER_OF*(Smart)[.](#out.ptr-1.sentence-1)
|
||
|
||
[2](#out.ptr-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5655)
|
||
|
||
*Returns*: out_ptr_t<Smart, P, Args&&...>(s, std::forward<Args>(args)...)[.](#out.ptr-2.sentence-1)
|
||
|
||
#### [20.3.4.3](#inout.ptr.t) Class template inout_ptr_t [[inout.ptr.t]](inout.ptr.t)
|
||
|
||
[1](#inout.ptr.t-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5662)
|
||
|
||
inout_ptr_t is a class template used to adapt types
|
||
such as smart pointers ([smartptr])
|
||
for functions that use output pointer parameters
|
||
whose dereferenced values may first be deleted
|
||
before being set to another allocated value[.](#inout.ptr.t-1.sentence-1)
|
||
|
||
[2](#inout.ptr.t-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5669)
|
||
|
||
[*Example [1](#inout.ptr.t-example-1)*: #include <memory>struct star_fish* star_fish_alloc();int star_fish_populate(struct star_fish** ps, const char* description);
|
||
|
||
struct star_fish_deleter {void operator() (struct star_fish* c) const noexcept;};
|
||
|
||
using star_fish_ptr = std::unique_ptr<star_fish, star_fish_deleter>;
|
||
|
||
int main(int, char*[]) { star_fish_ptr peach(star_fish_alloc()); // ...// used, need to re-makeint err = star_fish_populate(std::inout_ptr(peach), "caring clown-fish liker"); return err;}
|
||
|
||
A unique_ptr can be used with inout_ptr to be passed into an output pointer-style function[.](#inout.ptr.t-2.sentence-1)
|
||
|
||
The original value will be properly deleted
|
||
according to the function it is used with and
|
||
a new value reset in its place[.](#inout.ptr.t-2.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[ð](#lib:inout_ptr_t)
|
||
|
||
namespace std {template<class Smart, class Pointer, class... Args>class inout_ptr_t {public:constexpr explicit inout_ptr_t(Smart&, Args...);
|
||
inout_ptr_t(const inout_ptr_t&) = delete; constexpr ~inout_ptr_t(); constexpr operator Pointer*() const noexcept; operator void**() const noexcept; private: Smart& s; // *exposition only* tuple<Args...> a; // *exposition only* Pointer p; // *exposition only*};}
|
||
|
||
[3](#inout.ptr.t-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5720)
|
||
|
||
Pointer shall meet the [*Cpp17NullablePointer*](nullablepointer.requirements#:Cpp17NullablePointer "16.4.4.4 Cpp17NullablePointer requirements [nullablepointer.requirements]") requirements[.](#inout.ptr.t-3.sentence-1)
|
||
|
||
If Smart is a specialization of shared_ptr,
|
||
the program is ill-formed[.](#inout.ptr.t-3.sentence-2)
|
||
|
||
[*Note [1](#inout.ptr.t-note-1)*:
|
||
|
||
It is impossible to properly acquire unique ownership of the managed resource
|
||
from a shared_ptr given its shared ownership model[.](#inout.ptr.t-3.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[4](#inout.ptr.t-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5729)
|
||
|
||
Program-defined specializations of inout_ptr_t that depend on at least one program-defined type
|
||
need not meet the requirements for the primary template[.](#inout.ptr.t-4.sentence-1)
|
||
|
||
[5](#inout.ptr.t-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5734)
|
||
|
||
Evaluations of the conversion functions on the same object
|
||
may conflict ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#inout.ptr.t-5.sentence-1)
|
||
|
||
[ð](#lib:inout_ptr_t,constructor)
|
||
|
||
`constexpr explicit inout_ptr_t(Smart& smart, Args... args);
|
||
`
|
||
|
||
[6](#inout.ptr.t-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5744)
|
||
|
||
*Effects*: Initializes s with smart,a with std::forward<Args>(args)..., andp to either
|
||
|
||
- [(6.1)](#inout.ptr.t-6.1)
|
||
|
||
smart if is_pointer_v<Smart> is true,
|
||
|
||
- [(6.2)](#inout.ptr.t-6.2)
|
||
|
||
otherwise, smart.get()[.](#inout.ptr.t-6.sentence-1)
|
||
|
||
[7](#inout.ptr.t-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5754)
|
||
|
||
*Remarks*: An implementation can call s.release()[.](#inout.ptr.t-7.sentence-1)
|
||
|
||
[8](#inout.ptr.t-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5758)
|
||
|
||
[*Note [2](#inout.ptr.t-note-2)*:
|
||
|
||
The constructor is not noexcept to allow for a variety of non-terminating and safe implementation strategies[.](#inout.ptr.t-8.sentence-1)
|
||
|
||
For example, an intrusive pointer implementation with a control block
|
||
can allocate in the constructor and safely fail with an exception[.](#inout.ptr.t-8.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:inout_ptr_t,destructor)
|
||
|
||
`constexpr ~inout_ptr_t();
|
||
`
|
||
|
||
[9](#inout.ptr.t-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5773)
|
||
|
||
Let SP be*POINTER_OF_OR*(Smart, Pointer) ([[memory.general]](memory.general "20.2.1 General"))[.](#inout.ptr.t-9.sentence-1)
|
||
|
||
[10](#inout.ptr.t-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5777)
|
||
|
||
Let *release-statement* be s.release(); if an implementation does not call s.release() in the constructor[.](#inout.ptr.t-10.sentence-1)
|
||
|
||
Otherwise, it is empty[.](#inout.ptr.t-10.sentence-2)
|
||
|
||
[11](#inout.ptr.t-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5782)
|
||
|
||
*Effects*: Equivalent to:
|
||
|
||
- [(11.1)](#inout.ptr.t-11.1)
|
||
|
||
apply([&](auto&&... args) { s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a)); if is_pointer_v<Smart> is true;
|
||
|
||
- [(11.2)](#inout.ptr.t-11.2)
|
||
|
||
otherwise,*release-statement*;if (p) { apply([&](auto&&... args) { s.reset(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));} if the expressions.reset(static_cast<SP>(p), std::forward<Args>(args)...) is well-
|
||
formed;
|
||
|
||
- [(11.3)](#inout.ptr.t-11.3)
|
||
|
||
otherwise,*release-statement*;if (p) { apply([&](auto&&... args) { s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));} if is_constructible_v<Smart, SP, Args...> is true;
|
||
|
||
- [(11.4)](#inout.ptr.t-11.4)
|
||
|
||
otherwise, the program is ill-formed[.](#inout.ptr.t-11.sentence-1)
|
||
|
||
[ð](#inout.ptr.t-itemdecl:3)
|
||
|
||
`constexpr operator Pointer*() const noexcept;
|
||
`
|
||
|
||
[12](#inout.ptr.t-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5826)
|
||
|
||
*Preconditions*: operator void**() has not been called on *this[.](#inout.ptr.t-12.sentence-1)
|
||
|
||
[13](#inout.ptr.t-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5830)
|
||
|
||
*Returns*: addressof(const_cast<Pointer&>(p))[.](#inout.ptr.t-13.sentence-1)
|
||
|
||
[ð](#inout.ptr.t-itemdecl:4)
|
||
|
||
`operator void**() const noexcept;
|
||
`
|
||
|
||
[14](#inout.ptr.t-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5840)
|
||
|
||
*Constraints*: is_same_v<Pointer, void*> is false[.](#inout.ptr.t-14.sentence-1)
|
||
|
||
[15](#inout.ptr.t-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5844)
|
||
|
||
*Mandates*: is_pointer_v<Pointer> is true[.](#inout.ptr.t-15.sentence-1)
|
||
|
||
[16](#inout.ptr.t-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5848)
|
||
|
||
*Preconditions*: operator Pointer*() has not been called on *this[.](#inout.ptr.t-16.sentence-1)
|
||
|
||
[17](#inout.ptr.t-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5852)
|
||
|
||
*Returns*: A pointer value v such that:
|
||
|
||
- [(17.1)](#inout.ptr.t-17.1)
|
||
|
||
the initial value *v is equivalent to static_cast<void*>(p) and
|
||
|
||
- [(17.2)](#inout.ptr.t-17.2)
|
||
|
||
any modification of *v that is not followed by subsequent modification of *this affects the value of p during the destruction of *this,
|
||
such that static_cast<void*>(p) == *v[.](#inout.ptr.t-17.sentence-1)
|
||
|
||
[18](#inout.ptr.t-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5865)
|
||
|
||
*Remarks*: Accessing *v outside the lifetime of *this has undefined behavior[.](#inout.ptr.t-18.sentence-1)
|
||
|
||
[19](#inout.ptr.t-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5870)
|
||
|
||
[*Note [3](#inout.ptr.t-note-3)*:
|
||
|
||
reinterpret_cast<void**>(static_cast<Pointer*>(*this)) can be a viable implementation strategy for some implementations[.](#inout.ptr.t-19.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [20.3.4.4](#inout.ptr) Function template inout_ptr [[inout.ptr]](inout.ptr)
|
||
|
||
[ð](#lib:inout_ptr)
|
||
|
||
`template<class Pointer = void, class Smart, class... Args>
|
||
constexpr auto inout_ptr(Smart& s, Args&&... args);
|
||
`
|
||
|
||
[1](#inout.ptr-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5886)
|
||
|
||
Let P be Pointer if is_void_v<Pointer> is false,
|
||
otherwise *POINTER_OF*(Smart)[.](#inout.ptr-1.sentence-1)
|
||
|
||
[2](#inout.ptr-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5890)
|
||
|
||
*Returns*: inout_ptr_t<Smart, P, Args&&...>(s, std::forward<Args>(args)...)[.](#inout.ptr-2.sentence-1)
|