[util.smartptr.weak]

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

## 20.3 Smart pointers [[smartptr]](smartptr#util.smartptr.weak)

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

#### 20.3.2.3 Class template weak_ptr [util.smartptr.weak]

#### [20.3.2.3.1](#general) General [[util.smartptr.weak.general]](util.smartptr.weak.general)

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

To access the object, aweak_ptr can be converted to a shared_ptr using the member
function lock[.](#general-1.sentence-2)

namespace std {template<class T> class weak_ptr {public:using element_type = remove_extent_t<T>; // [[util.smartptr.weak.const]](#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]](#dest "20.3.2.3.3 Destructor"), destructorconstexpr ~weak_ptr(); // [[util.smartptr.weak.assign]](#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]](#mod "20.3.2.3.5 Modifiers"), modifiersconstexpr void swap(weak_ptr& r) noexcept; constexpr void reset() noexcept; // [[util.smartptr.weak.obs]](#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](#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[.](#general-2.sentence-1)

The template parameter T of weak_ptr may be an
incomplete type[.](#general-2.sentence-2)

#### [20.3.2.3.2](#const) Constructors [[util.smartptr.weak.const]](util.smartptr.weak.const)

[ð](#lib:weak_ptr,constructor)

`constexpr weak_ptr() noexcept;
`

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

[2](#const-2)

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

*Postconditions*: use_count() == 0[.](#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](#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*[.](#const-3.sentence-1)

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

[5](#const-5)

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

*Postconditions*: use_count() == r.use_count()[.](#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](#const-6)

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

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

[7](#const-7)

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

*Effects*: Move constructs a weak_ptr instance from r[.](#const-7.sentence-1)

[8](#const-8)

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

*Postconditions*: *this contains the old value of r[.](#const-8.sentence-1)

r is empty, stores a null pointer value, and r.use_count() == 0[.](#const-8.sentence-2)

#### [20.3.2.3.3](#dest) Destructor [[util.smartptr.weak.dest]](util.smartptr.weak.dest)

[ð](#lib:weak_ptr,destructor)

`constexpr ~weak_ptr();
`

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

#### [20.3.2.3.4](#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](#assign-1)

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

*Effects*: Equivalent to weak_ptr(r).swap(*this)[.](#assign-1.sentence-1)

[2](#assign-2)

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

*Returns*: *this[.](#assign-2.sentence-1)

[3](#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[.](#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](#assign-4)

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

*Effects*: Equivalent to weak_ptr(std​::​move(r)).swap(*this)[.](#assign-4.sentence-1)

[5](#assign-5)

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

*Returns*: *this[.](#assign-5.sentence-1)

#### [20.3.2.3.5](#mod) Modifiers [[util.smartptr.weak.mod]](util.smartptr.weak.mod)

[ð](#lib:swap,weak_ptr)

`constexpr void swap(weak_ptr& r) noexcept;
`

[1](#mod-1)

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

*Effects*: Exchanges the contents of *this and r[.](#mod-1.sentence-1)

[ð](#lib:reset,weak_ptr)

`constexpr void reset() noexcept;
`

[2](#mod-2)

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

*Effects*: Equivalent to weak_ptr().swap(*this)[.](#mod-2.sentence-1)

#### [20.3.2.3.6](#obs) Observers [[util.smartptr.weak.obs]](util.smartptr.weak.obs)

[ð](#lib:use_count,weak_ptr)

`constexpr long use_count() const noexcept;
`

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

[ð](#lib:expired,weak_ptr)

`constexpr bool expired() const noexcept;
`

[2](#obs-2)

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

*Returns*: use_count() == 0[.](#obs-2.sentence-1)

[ð](#lib:lock,weak_ptr)

`constexpr shared_ptr<T> lock() const noexcept;
`

[3](#obs-3)

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

*Returns*: expired() ? shared_ptr<T>() : shared_ptr<T>(*this), executed atomically[.](#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](#obs-4)

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

*Returns*: An unspecified value such that

- [(4.1)](#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)](#obs-4.2)

!owner_before(b) && !b.owner_before(*this) is true if and only if owner_equal(b) is true[.](#obs-4.sentence-1)

[ð](#lib:owner_hash,weak_ptr)

`size_t owner_hash() const noexcept;
`

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

Otherwise returns false[.](#obs-6.sentence-2)

[7](#obs-7)

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

*Remarks*: owner_equal is an equivalence relation[.](#obs-7.sentence-1)

#### [20.3.2.3.7](#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](#spec-1)

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

*Effects*: Equivalent to a.swap(b)[.](#spec-1.sentence-1)
