STD::SHARED_PTR(3)

πŸ’– std::shared_ptr< _Tp > πŸ’–

okay bestie, sit DOWN, because we are about to talk about std::shared_ptr< _Tp > β€” it's a Library Functions Manual page, it's iconic, it's the moment, and it is lowkey long, so hydrate first. 🫢


✨ NAME ✨

std::shared_ptr< _Tp > β€” a smart pointer with reference-counted copy semantics. no cap, that's the whole vibe. πŸ’…


🌸 SYNOPSIS 🌸

#include <memory>

πŸŽ€ Public Types

  • using element_type β€” the type pointed to by the stored pointer, aka remove_extent_t<_Tp>. yes it's a mouthful, it's giving template energy. πŸ¦‹
  • using weak_type β€” it's here, it exists, that's the tea. β˜•

πŸ‘‘ Public Member Functions

okay this is the big list, bestie. every single one, in order, no skipping, we are thorough in this house. πŸ’–

  • constexpr shared_ptr () noexcept β€” constructs an empty shared_ptr. the blank slate era. ✨
  • template<typename _Yp, typename = _Constructible<_Yp*>> shared_ptr (_Yp *__p) β€” constructs a shared_ptr that owns the pointer __p. 🫢
  • template<typename _Yp, typename _Deleter, typename = _Constructible<_Yp*, _Deleter>> shared_ptr (_Yp *__p, _Deleter __d) β€” constructs a shared_ptr that owns the pointer __p and the deleter __d. two for one, slay. πŸ’…
  • template<typename _Yp, typename _Deleter, typename _Alloc, typename = _Constructible<_Yp*, _Deleter, _Alloc>> shared_ptr (_Yp *__p, _Deleter __d, _Alloc __a) β€” constructs a shared_ptr that owns the pointer __p and the deleter __d. (the allocator __a is in the signature, bestie, I just report what the page says. πŸ™ˆ)
  • template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>> shared_ptr (auto_ptr< _Yp > &&__r) β€” it's there, in the list, doing its thing.
  • shared_ptr (const shared_ptr &) noexcept=default β€” the copy constructor. copies are literally the whole point of this class, we stan. πŸ’–
  • template<typename _Yp, typename = _Constructible<const shared_ptr<_Yp>&>> shared_ptr (const shared_ptr< _Yp > &__r) noexcept β€” if __r is empty, it constructs an empty shared_ptr; otherwise it constructs a shared_ptr that shares ownership with __r. friendship bracelet, but for memory. 🫢
  • template<typename _Yp> shared_ptr (const shared_ptr< _Yp > &__r, element_type *__p) noexcept β€” constructs a shared_ptr instance that stores __p and shares ownership with __r. two different things, don't mix them up, bestie. 😭
  • template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> shared_ptr (const weak_ptr< _Yp > &__r) β€” constructs a shared_ptr that shares ownership with __r and stores a copy of the pointer stored in __r. the weak one said "promote me" and it WORKED. πŸ”₯
  • template<typename _Deleter> shared_ptr (nullptr_t __p, _Deleter __d) β€” constructs a shared_ptr that owns a null pointer and the deleter __d. yes, you can own nothing. it's a mood. πŸ’€
  • template<typename _Deleter, typename _Alloc> shared_ptr (nullptr_t __p, _Deleter __d, _Alloc __a) β€” constructs a shared_ptr that owns a null pointer and the deleter __d. (allocator __a also along for the ride. πŸŽ€)
  • constexpr shared_ptr (nullptr_t) noexcept β€” constructs an empty shared_ptr. again. iconic of it. ✨
  • shared_ptr (shared_ptr &&__r) noexcept β€” move-constructs a shared_ptr instance from __r. bye, you're mine now. πŸ’…
  • template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>> shared_ptr (shared_ptr< _Yp > &&__r) noexcept β€” move-constructs a shared_ptr instance from __r. same energy, different _Yp. πŸ¦‹
  • template<typename _Yp> shared_ptr (shared_ptr< _Yp > &&__r, element_type *__p) noexcept β€” constructs a shared_ptr instance that stores __p and shares ownership with __r. (it's the aliasing thing again, she's everywhere. πŸ’œ)
  • template<typename _Tp1, typename> shared_ptr (std::auto_ptr< _Tp1 > &&__r) β€” listed, present, accounted for. that's it, that's the note. β˜•
  • template<typename _Yp, typename _Del, typename = _Constructible<unique_ptr<_Yp, _Del>>> shared_ptr (unique_ptr< _Yp, _Del > &&__r) β€” the unique_ptr one. taking over from its solo era. πŸ‘‘
  • element_type * get () const noexcept β€” returns the stored pointer. that's it. that's the function. 🫢
  • operator bool () const noexcept β€” returns true if the stored pointer is not null. vibe check, passed. βœ…
  • element_type & operator* () const noexcept β€” dereference, no extra notes, we move. πŸŽ€
  • element_type * operator-> () const noexcept β€” arrow, no extra notes, we move. πŸŽ€
  • template<typename _Yp> _Assignable< auto_ptr< _Yp > > operator= (auto_ptr< _Yp > &&__r) β€” assignment, listed as-is. πŸ’œ
  • shared_ptr & operator= (const shared_ptr &) noexcept=default β€” the copy assignment, defaulted, blessed. ✨
  • template<typename _Yp> _Assignable< const shared_ptr< _Yp > & > operator= (const shared_ptr< _Yp > &__r) noexcept β€” assignment from a shared_ptr< _Yp >. 🌸
  • shared_ptr & operator= (shared_ptr &&__r) noexcept β€” move assignment. 🌈
  • template<class _Yp> _Assignable< shared_ptr< _Yp > > operator= (shared_ptr< _Yp > &&__r) noexcept β€” move assignment, but with a different _Yp. πŸ”₯
  • template<typename _Yp, typename _Del> _Assignable< unique_ptr< _Yp, _Del > > operator= (unique_ptr< _Yp, _Del > &&__r) β€” assignment from a unique_ptr< _Yp, _Del >. πŸ‘‘
  • void reset () noexcept β€” reset, no extra notes. πŸ’…
  • template<typename _Yp> _SafeConv< _Yp > reset (_Yp *__p) β€” reset to __p. πŸŽ€
  • template<typename _Yp, typename _Deleter> _SafeConv< _Yp > reset (_Yp *__p, _Deleter __d) β€” reset with __p and deleter __d. πŸ¦‹
  • template<typename _Yp, typename _Deleter, typename _Alloc> _SafeConv< _Yp > reset (_Yp *__p, _Deleter __d, _Alloc __a) β€” reset with __p, deleter __d and allocator __a. the full trio. ✨
  • void swap (__shared_ptr< _Tp, _Lp > &__other) noexcept β€” exchanges both the owned pointer and the stored pointer. trade offer: I receive your pointers, you receive mine. πŸ’–
  • bool unique () const noexcept β€” returns true if use_count() == 1. main character energy, no roommates. πŸ‘‘
  • long use_count () const noexcept β€” if *this owns a pointer, returns the number of owners; otherwise, zero. the group chat member count. πŸ’…
    • template<typename _Tp1> bool owner_before (__shared_ptr< _Tp1, _Lp > const &__rhs) const noexcept β€” defines an ordering based on ownership. not the pointer, the ownership. iykyk. 🫢
    • template<typename _Tp1> bool owner_before (__weak_ptr< _Tp1, _Lp > const &__rhs) const noexcept β€” defines an ordering based on ownership. same deal, but with a __weak_ptr. 🌸

πŸ¦‹ Friends

  • template<typename _Yp, typename _Alloc, typename... _Args> shared_ptr< _NonArray< _Yp > > allocate_shared (const _Alloc &, _Args &&...)
  • template<typename _Yp, typename... _Args> shared_ptr< _NonArray< _Yp > > make_shared (_Args &&...)
  • class weak_ptr< _Tp >
heads up bestie: these are not member symbols. they're the extended fam. πŸ’œ
  • template<typename _Del, typename _Tp> _Del * get_deleter (const shared_ptr< _Tp > &__p) noexcept β€” 20.7.2.2.10 shared_ptr get_deleter.
  • template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> std::basic_ostream< _Ch, _Tr > & operator<< (std::basic_ostream< _Ch, _Tr > &__os, const __shared_ptr< _Tp, _Lp > &__p) β€” writes the stored pointer to an ostream. πŸŽ€
    • template<typename _Tp, typename _Up> bool operator== (const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept β€” equality operator for shared_ptr objects; it compares the stored pointers. πŸ‘‘
    • template<typename _Tp> bool operator== (const shared_ptr< _Tp > &__a, nullptr_t) noexcept β€” shared_ptr comparison with nullptr. ✨
    • template<typename _Tp> void swap (shared_ptr< _Tp > &__a, shared_ptr< _Tp > &__b) noexcept β€” swap overload for shared_ptr. πŸ”„
    • template<typename _Tp, typename _Up> shared_ptr< _Tp > static_pointer_cast (const shared_ptr< _Up > &__r) noexcept β€” converts the type of a shared_ptr, via static_cast. πŸ’…
    • template<typename _Tp, typename _Up> shared_ptr< _Tp > const_pointer_cast (const shared_ptr< _Up > &__r) noexcept β€” converts the type of a shared_ptr, via const_cast. πŸ’…
    • template<typename _Tp, typename _Up> shared_ptr< _Tp > dynamic_pointer_cast (const shared_ptr< _Up > &__r) noexcept β€” converts the type of a shared_ptr, via dynamic_cast. πŸ’…
    • template<typename _Tp, typename _Up> shared_ptr< _Tp > reinterpret_pointer_cast (const shared_ptr< _Up > &__r) noexcept β€” converts the type of a shared_ptr, via reinterpret_cast. πŸ’…
    • template<typename _Tp, typename _Up> shared_ptr< _Tp > static_pointer_cast (shared_ptr< _Up > &&__r) noexcept β€” converts the type of a shared_ptr rvalue, via static_cast. 🌈
    • template<typename _Tp, typename _Up> shared_ptr< _Tp > const_pointer_cast (shared_ptr< _Up > &&__r) noexcept β€” converts the type of a shared_ptr rvalue, via const_cast. 🌈
    • template<typename _Tp, typename _Up> shared_ptr< _Tp > dynamic_pointer_cast (shared_ptr< _Up > &&__r) noexcept β€” converts the type of a shared_ptr rvalue, via dynamic_cast. 🌈
    • template<typename _Tp, typename _Up> shared_ptr< _Tp > reinterpret_pointer_cast (shared_ptr< _Up > &&__r) noexcept β€” converts the type of a shared_ptr rvalue, via reinterpret_cast. 🌈
    • template<typename _Tp, typename _Alloc, typename... _Args> shared_ptr< _NonArray< _Tp > > allocate_shared (const _Alloc &__a, _Args &&... __args) β€” creates an object that is owned by a shared_ptr. 🫢
    • template<typename _Tp, typename... _Args> shared_ptr< _NonArray< _Tp > > make_shared (_Args &&... __args) β€” creates an object that is owned by a shared_ptr. 🫢

πŸ’– Detailed Description πŸ’–

template<typename _Tp>
    class std::shared_ptr< _Tp >

"A smart pointer with reference-counted copy semantics."

Since: C++11 ⭐

A shared_ptr object is either empty or it owns a pointer passed to the constructor. Copies of a shared_ptr share ownership of the same pointer. When the last shared_ptr that owns the pointer is destroyed or reset, the owned pointer is freed β€” either by delete or by invoking a custom deleter that was passed to the constructor. so like, the last one out turns off the lights. periodt. πŸ’…

A shared_ptr also stores another pointer, which is usually (but not always) the same pointer as the one it owns. You can grab that stored pointer by calling the get() member function. sneaky? a little. intentional? absolutely. πŸ™ˆ

The equality and relational operators for shared_ptr only compare the stored pointer returned by get(), not the owned pointer. if you wanna test whether two shared_ptr objects share ownership of the same pointer, go look at std::shared_ptr::owner_before and std::owner_less. iykyk. πŸ‘‘


πŸŽ€ Member Typedef Documentation πŸŽ€

template<typename _Tp> using std::shared_ptr< _Tp >::element_type

The type pointed to by the stored pointer, remove_extent_t<_Tp>. that's the whole note, bestie, short and sweet. πŸ“

πŸ’– Constructor & Destructor Documentation πŸ’–

okay bestie, this is the part where we learn how to birth a shared_ptr 🐣✨ there are SO many ways and honestly each one is its own little vibe. let's go one by one, no skipping, we're thorough in this house πŸ’…


🌸 shared_ptr ()

template<typename _Tp> std::shared_ptr< _Tp >::shared_ptr () [inline],
    [constexpr],  [noexcept]

Construct an empty shared_ptr. that's it, that's the girl. she's empty and she's thriving 🫢

Postcondition

  • use_count()==0 && get()==0

🌸 shared_ptr (const shared_ptr< _Tp > & )

template<typename _Tp> std::shared_ptr< _Tp >::shared_ptr (const shared_ptr<
    _Tp > & ) [default],  [noexcept]

Copy constructor. classic. the OG. copying one shared_ptr into another, and now they're both holding hands sharing ownership πŸ«‚ noexcept so she won't even stress about it.


🌸 shared_ptr (_Yp * __p)

template<typename _Tp> template<typename _Yp, typename =
    _Constructible<_Yp*>> std::shared_ptr< _Tp >::shared_ptr (_Yp * __p)
    [inline],  [explicit]

Construct a shared_ptr that owns the pointer __p. explicit bestie, so no sneaky implicit conversions, we're keeping it intentional πŸ’…

Parameters

  • __p β€” A pointer that is convertible to element_type*.

Postcondition

  • use_count() == 1 && get() == __p

Exceptions

  • std::bad_alloc, in which case delete __p is called. 😭 yeah if the allocation flops she still cleans up after herself, which is honestly more than most people do.

🌸 shared_ptr (_Yp * __p, _Deleter __d)

template<typename _Tp> template<typename _Yp, typename _Deleter, typename =
    _Constructible<_Yp*, _Deleter>> std::shared_ptr< _Tp >::shared_ptr (_Yp
    * __p, _Deleter __d) [inline]

Construct a shared_ptr that owns the pointer __p and the deleter __d. custom cleanup crew, we love a bespoke situation ✨

Parameters

  • __p β€” A pointer.
  • __d β€” A deleter.

Postcondition

  • use_count() == 1 && get() == __p

Exceptions

  • std::bad_alloc, in which case __d(__p) is called.
Requirements: _Deleter's copy constructor and destructor must not throw. periodt, that's non-negotiable 🚫

__shared_ptr will release __p by calling __d(__p)


🌸 shared_ptr (nullptr_t __p, _Deleter __d)

template<typename _Tp> template<typename _Deleter> std::shared_ptr< _Tp
    >::shared_ptr (nullptr_t __p, _Deleter __d) [inline]

Construct a shared_ptr that owns a null pointer and the deleter __d. yes she's holding nothing but she's still got opinions about how it gets cleaned up πŸ’€

Parameters

  • __p β€” A null pointer constant.
  • __d β€” A deleter.

Postcondition

  • use_count() == 1 && get() == __p

Exceptions

  • std::bad_alloc, in which case __d(__p) is called.
Requirements: _Deleter's copy constructor and destructor must not throw.

The last owner will call __d(__p)


🌸 shared_ptr (_Yp * __p, _Deleter __d, _Alloc __a)

template<typename _Tp> template<typename _Yp, typename _Deleter, typename
    _Alloc, typename = _Constructible<_Yp*, _Deleter, _Alloc>>
    std::shared_ptr< _Tp >::shared_ptr (_Yp * __p, _Deleter __d, _Alloc __a)
    [inline]

Construct a shared_ptr that owns the pointer __p and the deleter __d β€” but now we're also bringing an allocator __a to the function πŸŽ‰ main character energy, three whole parameters.

Parameters

  • __p β€” A pointer.
  • __d β€” A deleter.
  • __a β€” An allocator.

Postcondition

  • use_count() == 1 && get() == __p

Exceptions

  • std::bad_alloc, in which case __d(__p) is called.
Requirements: _Deleter's copy constructor and destructor must not throw. _Alloc's copy constructor and destructor must not throw. both of them. no exceptions. (pun intended.)

__shared_ptr will release __p by calling __d(__p)


🌸 shared_ptr (nullptr_t __p, _Deleter __d, _Alloc __a)

template<typename _Tp> template<typename _Deleter, typename _Alloc>
    std::shared_ptr< _Tp >::shared_ptr (nullptr_t __p, _Deleter __d, _Alloc
    __a) [inline]

Construct a shared_ptr that owns a null pointer and the deleter __d β€” with allocator __a in the mix too. the full trio, we're eating 🍽️

Parameters

  • __p β€” A null pointer constant.
  • __d β€” A deleter.
  • __a β€” An allocator.

Postcondition

  • use_count() == 1 && get() == __p

Exceptions

  • std::bad_alloc, in which case __d(__p) is called.
Requirements: _Deleter's copy constructor and destructor must not throw. _Alloc's copy constructor and destructor must not throw.

The last owner will call __d(__p)


🌸 the aliasing constructor (lvalue version) 🌈

template<typename _Tp> template<typename _Yp> std::shared_ptr< _Tp
    >::shared_ptr (const shared_ptr< _Yp > & __r, element_type * __p)
    [inline],  [noexcept]

Constructs a shared_ptr instance that stores __p and shares ownership with __r. this one is iconic, genuinely β€” it's how you point at a piece of something while keeping the whole thing alive πŸ¦‹

Parameters

  • __r β€” A shared_ptr.
  • __p β€” A pointer that will remain valid while *__r is valid.

Postcondition

  • get() == __p && use_count() == __r.use_count()

This can be used to construct a shared_ptr to a sub-object of an object managed by an existing shared_ptr. The complete object will remain valid while any shared_ptr owns it, even if they don't store a pointer to the complete object.

shared_ptr<pair<int,int>> pii(new pair<int,int>());
shared_ptr<int> pi(pii, &pii->first);
assert(pii.use_count() == 2);

🌸 the aliasing constructor (rvalue version) 🌈

template<typename _Tp> template<typename _Yp> std::shared_ptr< _Tp
    >::shared_ptr (shared_ptr< _Yp > && __r, element_type * __p) [inline],
    [noexcept]

Constructs a shared_ptr instance that stores __p and shares ownership with __r. same deal as above but she's moving in, taking the whole vibe with her πŸ’…

Parameters

  • __r β€” A shared_ptr.
  • __p β€” A pointer that will remain valid while *__r is valid.

Postcondition

  • get() == __p && !__r.use_count() && !__r.get()

Since

  • C++17

This can be used to construct a shared_ptr to a sub-object of an object managed by an existing shared_ptr. The complete object will remain valid while any shared_ptr owns it, even if they don't store a pointer to the complete object.

shared_ptr<pair<int,int>> pii(new pair<int,int>());
shared_ptr<int> pi1(pii, &pii->first);
assert(pii.use_count() == 2);
shared_ptr<int> pi2(std::move(pii), &pii->second);
assert(pii.use_count() == 0);

🌸 shared_ptr (const shared_ptr< _Yp > & __r) β€” the converting copy ctor 🌸

template<typename _Tp> template<typename _Yp, typename =
    _Constructible<const shared_ptr<_Yp>&>> std::shared_ptr< _Tp
    >::shared_ptr (const shared_ptr< _Yp > & __r) [inline],  [noexcept]

If __r is empty, constructs an empty shared_ptr; otherwise construct a shared_ptr that shares ownership with __r. either way she matches the energy of __r, and __r is always right πŸ’–

Parameters

  • __r β€” A shared_ptr.

Postcondition

  • get() == __r.get() && use_count() == __r.use_count()

🌸 shared_ptr (shared_ptr< _Tp > && __r) β€” the move ctor 🌸

template<typename _Tp> std::shared_ptr< _Tp >::shared_ptr (shared_ptr< _Tp >
    && __r) [inline],  [noexcept]

Move-constructs a shared_ptr instance from __r. she takes what __r had and leaves __r with nothing. iconic. no notes. πŸ”₯

Parameters

  • __r β€” A shared_ptr rvalue.

Postcondition

  • *this contains the old value of __r, __r is empty.

🌸 shared_ptr (shared_ptr< _Yp > && __r) β€” the converting move ctor 🌸

template<typename _Tp> template<typename _Yp, typename =
    _Constructible<shared_ptr<_Yp>>> std::shared_ptr< _Tp >::shared_ptr
    (shared_ptr< _Yp > && __r) [inline],  [noexcept]

Move-constructs a shared_ptr instance from __r. same girl, different _Yp, still slaying πŸ’…

Parameters

  • __r β€” A shared_ptr rvalue.

Postcondition

  • *this contains the old value of __r, __r is empty.

🌸 shared_ptr (const weak_ptr< _Yp > & __r) 🌸

template<typename _Tp> template<typename _Yp, typename =
    _Constructible<const weak_ptr<_Yp>&>> std::shared_ptr< _Tp >::shared_ptr
    (const weak_ptr< _Yp > & __r) [inline],  [explicit]

Constructs a shared_ptr that shares ownership with __r and stores a copy of the pointer stored in __r. she's leveling up from weak_ptr to shared_ptr and honestly? glow up 🌟 explicit, so you gotta mean it.

Parameters

  • __r β€” A weak_ptr.

Postcondition

  • use_count() == __r.use_count()

Exceptions

  • bad_weak_ptr when __r.expired(), in which case the constructor has no effect. 😭 if the thing she was weakly vibing with is gone, she throws β€” and she throws before changing anything, so no mess left behind.

🌸 shared_ptr (nullptr_t ) 🌸

template<typename _Tp> std::shared_ptr< _Tp >::shared_ptr (nullptr_t )
    [inline],  [constexpr],  [noexcept]

Construct an empty shared_ptr. from an actual nullptr_t this time. she's empty but make it constexpr ✨

Postcondition

  • use_count() == 0 && get() == nullptr

πŸ’œ Member Function Documentation πŸ’œ

okay these are all marked [inherited] because they come down from std::__shared_ptr< _Tp, _Lp >, the base class doing the actual heavy lifting. she's the blueprint, the shared_ptr you see is the outfit πŸ’…


πŸ¦‹ get ()

template<typename _Tp, _Lock_policy _Lp> element_type * std::__shared_ptr<
    _Tp, _Lp >::get () const [inline],  [noexcept],  [inherited]

Return the stored pointer. that's it. that's the whole function. she's simple and she knows what she wants 🫢


πŸ¦‹ operator bool ()

template<typename _Tp, _Lock_policy _Lp> std::__shared_ptr< _Tp, _Lp
    >::operator bool () const [inline],  [explicit],  [noexcept],
    [inherited]

Return true if the stored pointer is not null. so you can just go if (ptr) { ... } and she'll tell you the truth πŸ™ˆ explicit so no accidental int conversions, we're not doing that today.


πŸ¦‹ owner_before (__shared_ptr< _Tp1, _Lp > const & __rhs)

template<typename _Tp, _Lock_policy _Lp> template<typename _Tp1> bool
    std::__shared_ptr< _Tp, _Lp >::owner_before (__shared_ptr< _Tp1, _Lp >
    const & __rhs) const [inline],  [noexcept],  [inherited]

Define an ordering based on ownership. This function defines a strict weak ordering between two shared_ptr or weak_ptr objects, such that one object is less than the other unless they share ownership of the same pointer, or are both empty.

like, it's not comparing the pointers, bestie, it's comparing who owns what. crucial distinction, iykyk πŸ‘‘


πŸ¦‹ owner_before (__weak_ptr< _Tp1, _Lp > const & __rhs)

template<typename _Tp, _Lock_policy _Lp> template<typename _Tp1> bool
    std::__shared_ptr< _Tp, _Lp >::owner_before (__weak_ptr< _Tp1, _Lp >
    const & __rhs) const [inline],  [noexcept],  [inherited]

Define an ordering based on ownership. This function defines a strict weak ordering between two shared_ptr or weak_ptr objects, such that one object is less than the other unless they share ownership of the same pointer, or are both empty.

same vibe as the one above, except __rhs is a weak_ptr this time. still no comparison of the raw pointers. still iconic. πŸŽ€


πŸ¦‹ swap (__shared_ptr< _Tp, _Lp > & __other)

template<typename _Tp, _Lock_policy _Lp> void std::__shared_ptr< _Tp, _Lp
    >::swap (__shared_ptr< _Tp, _Lp > & __other) [inline],  [noexcept],
    [inherited]

Exchange both the owned pointer and the stored pointer. two things swap at once, not just one. trade szn 🀝


πŸ¦‹ unique ()

template<typename _Tp, _Lock_policy _Lp> bool std::__shared_ptr< _Tp, _Lp
    >::unique () const [inline],  [noexcept],  [inherited]

Return true if use_count() == 1. she's the only one. no competition. main character, literally πŸ‘‘βœ¨


πŸ¦‹ use_count ()

template<typename _Tp, _Lock_policy _Lp> long std::__shared_ptr< _Tp, _Lp
    >::use_count () const [inline],  [noexcept],  [inherited]

If *this owns a pointer, return the number of owners, otherwise zero. so she's counting the group chat members πŸ«‚ and if nobody owns anything, the answer is a flat 0, no cap.


🌈 Author 🌈

Generated automatically by Doxygen for libstdc++ from the source code. so like, not a human, a tool. still ate though πŸ’…


and that's a wrap on this page bestie πŸŽ€ this was std::shared_ptr< _Tp >(3) from libstdc++, brought to you by the Doxygen auto-generation machine ✨ go forth and share ownership responsibly, and remember: use_count() == 1 is a moment, not a lifestyle πŸ’–πŸ¦‹

πŸ“¦ where this page comes from
  • arch rolling: gcc 16.2.1+r23+gd564253eb6c8-1 Β· GPL-3.0-or-later WITH GCC-exception-3.1 AND GFDL-1.3-or-later
  • fedora 44: libstdc++-docs 16.0.1-0.10.fc44 Β· GPL-3.0-or-later AND LGPL-3.0-or-later AND (GPL-3.0-or-later WITH GCC-exception-3.1) AND (GPL-3.0-or-later WITH Texinfo-exception) AND (LGPL-2.1-or-later WITH GCC-exception-2.0) AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND (GPL-2.0-or-later WITH GNU-compiler-exception) AND BSL-1.0 AND GFDL-1.3-or-later AND Linux-man-pages-copyleft-2-para AND SunPro AND BSD-1-Clause AND BSD-2-Clause AND BSD-2-Clause-Views AND BSD-3-Clause AND BSD-4-Clause AND BSD-Source-Code AND Zlib AND MIT AND Apache-2.0 AND (Apache-2.0 WITH LLVM-Exception) AND ZPL-2.1 AND ISC AND LicenseRef-Fedora-Public-Domain AND HP-1986 AND curl AND Martin-Birgmeier AND HPND-Markus-Kuhn AND dtoa AND SMLNJ AND AMD-newlib AND OAR AND HPND-merchantability-variant AND HPND-Intel
  • fedora 44: libstdc++-docs 16.2.1-2.fc44
  • fedora 44: libstdc++-docs 16.2.1-3.fc44 Β· GPL-3.0-or-later AND LGPL-3.0-or-later AND (GPL-3.0-or-later WITH GCC-exception-3.1) AND (GPL-3.0-or-later WITH Texinfo-exception) AND (LGPL-2.1-or-later WITH GCC-exception-2.0) AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND (GPL-2.0-or-later WITH GNU-compiler-exception) AND BSL-1.0 AND GFDL-1.3-or-later AND Linux-man-pages-copyleft-2-para AND SunPro AND BSD-1-Clause AND BSD-2-Clause AND BSD-2-Clause-Views AND BSD-3-Clause AND BSD-4-Clause AND BSD-Source-Code AND Zlib AND MIT AND Apache-2.0 AND (Apache-2.0 WITH LLVM-Exception) AND ZPL-2.1 AND ISC AND LicenseRef-Fedora-Public-Domain AND HP-1986 AND curl AND Martin-Birgmeier AND HPND-Markus-Kuhn AND dtoa AND SMLNJ AND AMD-newlib AND OAR AND HPND-merchantability-variant AND HPND-Intel
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms