Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::shared_ptr::owner_before and std::owner_less: What exactly is meant by "owner-based order"?

Tags:

c++

c++11

I have found a few discussions on this but nothing appears to ever specify what "owner based order" actually is.

Is it effectively evaluating < on the value of the owned pointer memory addresses?

like image 750
Steven Lu Avatar asked Feb 17 '14 16:02

Steven Lu


People also ask

What is Owner_before?

std::shared_ptr<T>::owner_beforeThis ordering is used to make shared and weak pointers usable as keys in associative containers, typically through std::owner_less.

What is a shared_ptr in C++?

The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.

What is control block in shared_ptr?

Pointer to Managed Object (or Managed Object) A control block contains a pointer to the managed object, which is used for deleting the object. One interesting fact is that the managed pointer in the control block could be different in type (and even value) from the raw pointer in the shared_ptr.

What library is shared_ptr in?

If your C++ implementation supports the C++ TR1 library extensions, then std::tr1::shared_ptr will likely be in <memory> (Microsoft Visual C++) or <tr1/memory> (g++'s libstdc++).


2 Answers

It defines an arbitrary strict weak ordering under which two pointers are equivalent if and only if they share ownership or are both empty.

Equivalence is defined in the usual way:

bool equivalent(p1, p2) {
    return !p1.owner_before(p2) && !p2.owner_before(p1);
}

This doesn't necessarily mean that they point to the same object. Two pointers can point to different objects but still share ownership:

struct thing {int n;};
shared_ptr<thing> t1 = make_shared<thing>();
shared_ptr<int>   t2(t1, &t1->n);

assert(t1 != t2);          // point to different objects
assert(equivalent(t1,t2)); // share ownership

Likewise, two pointers can point to the same object without sharing:

thing t;
shared_ptr<thing> t1(&t, some_deleter());
shared_ptr<thing> t2(&t, some_deleter());

assert(t1 == t2);            // point to the same object
assert(!equivalent(t1, t2)); // don't share ownership

(Of course, this would be disastrous with the default deleter since both would try to delete the object; but there are sensible applications for this kind of thing with a suitable custom deleter).

In practice, this could be implemented by comparing the address of the internal structure used for the shared reference count.

like image 101
Mike Seymour Avatar answered Nov 15 '22 16:11

Mike Seymour


Semantically, it means that two shared_ptrs compare equal if an only if they share ownership or are both nullptr, and otherwise there is some consistent ordering of shared_ptrs.

Effectively, this ordering is implemented by comparing the internal pointer to the reference control block that is shared between shared_ptrs that "share ownership." Note that it is possible to create shared_ptrs with differing get() that share ownership via the constructor:

template< class Y >
shared_ptr( const shared_ptr<Y>& r, T *ptr );

Which is useful, e.g, for handing out pointers to members of an object held by shared_ptr.

like image 37
Casey Avatar answered Nov 15 '22 16:11

Casey