Boost logo

Boost :

Subject: Re: [boost] Looking for thoughts on a new smart pointer: shared_ptr_nonnull
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2013-10-08 18:44:49


On 10/9/2013 3:26 AM, Quoth Thorsten Ottosen:
> Another benefit of this approach is that we can create different
> behaviors without relying on the absurd subtleties of the
> preprocessor:
>
> typedef boost::shared_ptr<T> SharedT; // normal shared_ptr typedef
> boost::shared_ptr<assert_non_null<T>> NonNullSharedT; // no null
> enforced by assertions typedef
> boost::shared_ptr<enforce_non_null<T>> NeverNullSharedT; // no null
> enfoced by exceptions

throw_on_null might be better for the latter, just to be explicit,
although it does break the "non_null" naming similarity.

> The shared_ptr implementation would have to check its template
> argument and emit special code in a few places. This is very easy to
> do, and far easier than specializing/wrapping the class.

Ok, I was assuming something that did not modify the existing shared_ptr
implementation. If you allow that then things get much tidier.

> I suppose there is still a need to break cycles. Why would this have
> changed.

But part of the semantics of weak_ptr is that it can point to a
non-existent (expired) object, which is effectively the same as a null
one. And lock() must be able to return an empty pointer, so it would
have to be a regular shared_ptr<T> rather than a
shared_ptr<*_non_null<T>>. So I'm not sure if a weak_ptr<*_non_null<T>>
could make sense.

Also, as someone pointed out earlier (apologies, I've lost track of the
original post), the shared_ptr<T>(weak_ptr<T>) constructor already
throws if the weak_ptr is empty or expired. (There's a nothrow variant
of the constructor but as that is undocumented and requires using a
detail class I think that's not intended for public use.)

Although, just to be confusing (it's documented behaviour though), this
code will throw:

    boost::shared_ptr<int> s1;
    boost::weak_ptr<int> w(s1);
    boost::shared_ptr<int> s2(w); // throws bad_weak_ptr

And this code will not:

    boost::shared_ptr<int> s1((int*)0);
    boost::weak_ptr<int> w(s1);
    boost::shared_ptr<int> s2(w); // doesn't throw; s2 is false


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk