std::weak_p...owner_before(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

✨ NAME ✨

bestie, welcome to the manual page for std::weak_p...owner_before(3) β€” aka std::weak_ptr::owner_before πŸ’…

It’s literally std::weak_ptr::owner_before, no cap πŸ‘‘


🌸 Synopsis 🌸

template< class Y >
bool owner_before( const weak_ptr<Y>& other ) const noexcept;
template< class Y >
bool owner_before( const std::shared_ptr<Y>& other ) const noexcept;

Okay so this checks whether this weak_ptr precedes other in an implementation defined owner-based order β€” that’s owner-based, not value-based, bestie 😌

The order is set up so that two smart pointers compare equivalent only if they are both empty, or if they both own the same object. And yes, that still holds even if the values of the pointers you get from get() are different β€” like, say, because they point at different subobjects within the same object. Iconic behavior, honestly 🫢

This ordering is what makes shared and weak pointers usable as keys in associative containers, typically through std::owner_less ✨


πŸ’… Parameters πŸ’…

  • other β€” the std::shared_ptr or std::weak_ptr to be compared πŸ‘€

πŸŽ€ Return value πŸŽ€

true if *this precedes other, false otherwise. Common implementations compare the addresses of the control blocks 🧚


πŸ¦‹ Example πŸ¦‹

// Run this code

#include <iostream>
#include <memory>

struct Foo
{
    int n1;
    int n2;
    Foo(int a, int b) : n1(a), n2(b) {}
};

int main()
{
    auto p1 = std::make_shared<Foo>(1, 2);
    std::shared_ptr<int> p2(p1, &p1->n1);
    std::shared_ptr<int> p3(p1, &p1->n2);

    std::cout << std::boolalpha
              << "p2 < p3 " << (p2 < p3) << '\n'
              << "p3 < p2 " << (p3 < p2) << '\n'
              << "p2.owner_before(p3) " << p2.owner_before(p3) << '\n'
              << "p3.owner_before(p2) " << p3.owner_before(p2) << '\n';

    std::weak_ptr<int> w2(p2);
    std::weak_ptr<int> w3(p3);
    std::cout
//            << "w2 < w3 " << (w2 < w3) << '\n' // won't compile
//            << "w3 < w2 " << (w3 < w2) << '\n' // won't compile
              << "w2.owner_before(w3) " << w2.owner_before(w3) << '\n'
              << "w3.owner_before(w2) " << w3.owner_before(w2) << '\n';
}

Output:

p2 < p3 true
p3 < p2 false
p2.owner_before(p3) false
p3.owner_before(p2) false
w2.owner_before(w3) false
w3.owner_before(w2) false

πŸ’€ Defect reports πŸ’€

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

  • LWG 2083 β€” Applied to: C++11 β€” Behavior as published: owner_before was not declared const β€” Correct behavior: declared const
  • LWG 2942 β€” Applied to: C++11 β€” Behavior as published: owner_before was not declared noexcept β€” Correct behavior: declared noexcept

πŸ‘‘ See also πŸ‘‘

  • owner_less β€” provides mixed-type owner-based ordering of shared and weak pointers (C++11) (class template) 🌈

mwah πŸ’‹ β€” source/version and date, bestie: http://cppreference.com, version 2024.06.10, manual page std::weak_p...owner_before(3). That’s the footer, and yes, it ate πŸ’–

πŸ“¦ where this page comes from