5

For boost::weak_ptr the operator< is defined, so that it can be used in associative containers.

My question is: Is the sort order of several weak_ptr objects stable even when some of them change to a refcount of zero? Doesn't that mess with containers like std::set?

Example:

using namespace boost;
shared_ptr<A> sptrA1(new A);
weak_ptr<A> wptrA1 = sptrA1;
weak_ptr<A> wptrA2;

{ // begin Scope 1
    shared_ptr<A> sptrA2(new A);
    wptrA2 = sptrA2;
    assert(wptrA1 < wptrA2); // assert #1
}
assert(wptrA1 < wptrA2); // assert #2
  • Will assert #2 always hold true if assert #1 is true?
  • Is wptrA2 in the same state before and after the Scope 1?
Hannah S.
  • 3,081
  • 3
  • 20
  • 27

3 Answers3

5

In the current implementation of boost::weak_ptr, operator< compares a pointer to an internal reference-count-tracking structure. This structure is not freed until all strong and weak references are removed, so it remains safe to use operator< even if the pointed-to user data has been freed due to a lack of strong references.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • Interesting. I was confused by the documentation of use_count in http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/weak_ptr.htm. It states "Returns: 0 if *this is empty" however according to your answer the reverse (*this is empty if it returns 0) is not true, right? (If empty is defined as the state obtained from default constructing a weak_ptr.) – Hannah S. Jan 21 '11 at 18:22
  • I haven't made any statements about what `use_count` does here :) That said, the internal reference counting structure keeps two counts - one for strong references only (when it hits zero, the pointed-to-object is destroyed) and one that includes both strong and weak references (when it hits zero, the reference-counting structure is destroyed). The `use_count` function might be looking at the strong-count-only one, but I haven't investigated at all, so verify for yourself. :) – bdonlan Jan 21 '11 at 19:19
2

Read about weak_ptr comparision here.

Öö Tiib
  • 10,809
  • 25
  • 44
1

Use std::owner_less. This compares the pointer of the use count, not the pointer itself. For example:

typedef std::weak_ptr<int> IntWPtr;
std::set<IntWPtr, std::owner_less<IntWPtr> > m_set;
tgoodhart
  • 3,111
  • 26
  • 37