
I'm wondering why there is not an efficient built-in way to check whether two things (e.g. a shared_ptr and a weak_ptr, but any combination should work) refer to the same object. In my implementation, I found that a handy thing to have. In changing code that uses a different home-brew smart pointer, I have to achieve this. The only way I see is to first resolve the weak pointer, and then compare the get() from each. That needlessly yoyo's the reference count, which is a horribly expensive atomic operation. I find that in the new C++ standard it refers to a owner_before ordering function, which is a bit more obscure than just comparing the pointers. So I'm wondering why this is not provided. Is there some reason why the feature is obscured, for portability? —John

On Fri, Sep 16, 2011 at 11:11 AM, John M. Dlugosz
I'm wondering why there is not an efficient built-in way to check whether two things (e.g. a shared_ptr and a weak_ptr, but any combination should work) refer to the same object.
It depends what you mean by "refer to the same object". You can use
!(p1

On 9/16/2011 1:24 PM, Emil Dotchevski wrote:
On Fri, Sep 16, 2011 at 11:11 AM, John M. Dlugosz
wrote: I'm wondering why there is not an efficient built-in way to check whether two things (e.g. a shared_ptr and a weak_ptr, but any combination should work) refer to the same object.
It depends what you mean by "refer to the same object". You can use !(p1
I guess that is what I'm trying to figure out. If two smart pointers manage the lifetime of the same entity, how can they not get() the same pointer? I see that they might be different addresses if they refer to the object by different types, but that is true for regular pointers, and bringing them to a common base class would allow them to compare equal.

On Saturday, September 17, 2011, John M. Dlugosz wrote:
I guess that is what I'm trying to figure out. If two smart pointers manage the lifetime of the same entity, how can they not get() the same pointer? I see that they might be different addresses if they refer to the object by different types, but that is true for regular pointers, and bringing them to a common base class would allow them to compare equal.
shared_ptr also has an aliasing copy constructor, where you can give it an arbitrary pointer. So, you might make a shared_ptr that points at a struct and a shared_ptr that points at a member of the same struct, but they both share the same reference count and deleter.

As a special case of that, you can even have a shared_ptr that returns 0
from get() yet manages the lifetime of something.
On Saturday, September 17, 2011, Frank Mori Hess
On Saturday, September 17, 2011, John M. Dlugosz wrote:
I guess that is what I'm trying to figure out. If two smart pointers manage the lifetime of the same entity, how can they not get() the same pointer? I see that they might be different addresses if they refer to the object by different types, but that is true for regular pointers, and bringing them to a common base class would allow them to compare equal.
shared_ptr also has an aliasing copy constructor, where you can give it an arbitrary pointer. So, you might make a shared_ptr that points at a struct and a shared_ptr that points at a member of the same struct, but they both share the same reference count and deleter.

shared_ptr also has an aliasing copy constructor, where you can give it an arbitrary pointer. So, you might make a shared_ptr that points at a struct and a shared_ptr that points at a member of the same struct, but they both share the same reference count and deleter.
Could you elaborate a bit? struct inner { //... }; struct outer { inner inner_; }; Do you mean that one can make shared_ptr<inner> from shared_ptr<outer>?

On Tue, Sep 20, 2011 at 05:43:49PM +0300, Igor R wrote:
shared_ptr also has an aliasing copy constructor, where you can give it an arbitrary pointer. So, you might make a shared_ptr that points at a struct and a shared_ptr that points at a member of the same struct, but they both share the same reference count and deleter.
Could you elaborate a bit?
struct inner { //... }; struct outer { inner inner_; };
Do you mean that one can make shared_ptr<inner> from shared_ptr<outer>?
Very much that, yes. shared_ptr<outer> o = make_shared<outer>(); shared_ptr<inner> i = shared_ptr<inner>(o, &o->i); The aliasing ctor holds the second pointer argument, while using the refcounting of the first argument. There's no restriction that the pointer has to be to inside the object at all, but it tends to be the common use case. -- Lars Viklund | zao@acc.umu.se

Very much that, yes.
shared_ptr<outer> o = make_shared<outer>(); shared_ptr<inner> i = shared_ptr<inner>(o, &o->i);
The aliasing ctor holds the second pointer argument, while using the refcounting of the first argument.
There's no restriction that the pointer has to be to inside the object at all, but it tends to be the common use case.
Wow! I never payed attention to that ctor. Great feature. I think it's worth to be highlighted somewhere in the docs. Thanks.

Igor R wrote, about the aliasing constructor:
Wow! I never payed attention to that ctor. Great feature. I think it's worth to be highlighted somewhere in the docs.
This is a relatively late addition (shared_ptr it was already in std:: and part of the draft standard when the aliasing constructor was added). It's worth noting that it was always possible to do this: http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/sp_techniques.html#anoth... (you just need to realize that the "another smart pointer" can be shared_ptr) but the aliasing constructor made it more efficient and more explicit (with respect to the shared ownership). Getting back to the original question, it's possible to have two shared_ptr<T> instances that share ownership and have different get() pointers, without any aliasing tricks: struct X {}; struct Y: X {}; struct Z: X {}; struct W: Y, Z {}; shared_ptr<W> pw( new W ); shared_ptr<Y> py( pw ); shared_ptr<Z> pz( pw ); shared_ptr<X> px( py ); shared_ptr<X> px2( pz );
participants (7)
-
Emil Dotchevski
-
Emil Dotchevski
-
Frank Mori Hess
-
Igor R
-
John M. Dlugosz
-
Lars Viklund
-
Peter Dimov