Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8488259
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T21:28:54+00:00 2026-06-10T21:28:54+00:00

I want to compare two std::weak_ptr’s or one std::weak_ptr and one std::shared_ptr for equality.

  • 0

I want to compare two std::weak_ptr’s or one std::weak_ptr and one std::shared_ptr for equality.

What I want to know is whether the object each of the weak_ptr’s/shared_ptr’s point to is the same.
The comparison should yield negative results not just if the addresses don’t match, but also if the underlying object was deleted and then reconstructed with the same address by chance.

So basically, I want this assertion to hold even if the allocator reserves the same address:

auto s1 = std::make_shared<int>(43);
std::weak_ptr<int> w1(s1);

s1.reset();

auto s2 = std::make_shared<int>(41);
std::weak_ptr<int> w2(s2);

assert(!equals(w1,w2));

The weak_ptr templates do not provide equality operators, and as I understood that’s for a good reason.

So a naive implementation would look like this:

template <typename T, typename U>
inline bool naive_equals(const std::weak_ptr<T>& t, const std::weak_ptr<U>& u)
{
    return !t.expired() && t.lock() == u.lock();
}

template <typename T, typename U>
inline bool naive_equals(const std::weak_ptr<T>& t, const std::shared_ptr<U>& u)
{
    return !t.expired() && t.lock() == u;
}

If the first weak_ptr expired in the meantime, it yields 0. If not, I upgrade the weak_ptr to a shared_ptr and compare the addresses.

The problem with this is that i have to lock the weak_ptr’s twice (once)! I’m afraid that takes too much time.

I came up with this:

template <typename T, typename U>
inline bool equals(const std::weak_ptr<T>& t, const std::weak_ptr<U>& u)
{
    return !t.owner_before(u) && !u.owner_before(t);
}


template <typename T, typename U>
inline bool equals(const std::weak_ptr<T>& t, const std::shared_ptr<U>& u)
{
    return !t.owner_before(u) && !u.owner_before(t);
}

Which checks if the owner block of u is not “before” t’s and t’s not before u’s, so t == u.

Does this work as I intend it? Do two weak_ptr’s created from distinct shared_ptr’s always compare as non-equal this way?
Or did I miss something?

Edit: Why do I want to do this in the first place?
I want to have a container with shared pointers, and I want to hand out references to the objects in it.
I can’t use iterators, since they may be invalidated. I could hand out (integer) ID’s, but that leads to problems with uniqueness and would require a map type and complicate search/insertion/removal operations.
The idea is to use a std::set and give out the pointers themselves (capsuled in a wrapper class) as keys, so that clients can use the weak_ptr’s to access the objects in the set.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T21:28:56+00:00Added an answer on June 10, 2026 at 9:28 pm

    Completely rewriting this answer because I totally misunderstood. This is a tricky thing to get right!

    The usual implementation of std::weak_ptr and std::shared_ptr that is consistent with the standard is to have two heap objects: the managed object, and a control block. Each shared pointer that refers to the same object contains a pointer to the object and to the control block, and each weak pointer likewise. The control block keeps a record of the number of shared pointers and the number of weak pointers, and deallocates the managed object when the number of shared pointers reaches 0; the control block itself is deallocated when the number of weak pointers also reaches 0.

    This is complicated by the fact that the object pointer in a shared or weak pointer can point to a subobject of the actual managed object, e.g. a base class, a member, or even another heap object that is owned by the managed object.

    S0 ----------______       MO <------+
       \__             `----> BC        |
          \_ _______--------> m1        |
         ___X__               m2 --> H  |
    S1 -/      \__ __----------------^  |
        \___ _____X__                   |
        ____X________\__                |
    W0 /----------------`---> CB -------+  
                              s = 2 
                              w = 1 
                                   
    

    Here we have two shared pointers pointing respectively to a base class of the managed object and to a member, and a weak pointer pointing to a heap object owned by the managed object; the control block records that two shared pointers and one weak pointer exist. The control block also has a pointer to the managed object, which it uses to delete the managed object when it expires.

    The owner_before / owner_less semantics are to compare shared and weak pointers by the address of their control block, which is guaranteed not to change unless the pointer itself is modified; even if a weak pointer expires because all shared pointers have been destructed, its control block still exists until all weak pointers have also been destructed.

    So your equals code is absolutely correct and thread safe.

    The issue is that it’s not consistent with shared_ptr::operator== because that compares the object pointers, and two shared pointers with the same control block can point to different objects (as above).

    For consistency with shared_ptr::operator==, writing t.lock() == u will be absolutely fine; note however that if it returns true then it’s still not definite that the weak pointer is a weak pointer of the other shared pointer; it could be an alias pointer and so could still expire in following code.

    However, comparing control blocks has less overhead (because it doesn’t need to look at the control block) and will give the same results as == if you’re not using alias pointers.


    C++26 is highly likely to add owner_equal and owner_hash function object templates, allowing the use of weak_ptr as key type in unordered containers. Given owner_equal it actually becomes sensible to compare weak pointers for equality, as you can safely compare the control block pointer then the object pointer, since if two weak pointers have the same control block then you know that either both or neither are expired.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I want to compare two Java Map s by a simple hash. Each object
I want to compare two strings for equality when either or both can be
I want to compare two arrays, one coming from a shoppingcart and the other
I want to compare two files (one file is located on local location and
I would like to compare two columns in the same table. I want to
I want to compare two List of different lengths and/or same length. The first
I want to compare two files and see if they are the same or
I want to compare two results one is stored in the first query, and
I want to compare two double values till the second digit from decimal point.
I want to compare two text files that i have generated from one of

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.