Boost logo

Boost :

Subject: Re: [boost] Looking for thoughts on a new smart pointer: shared_ptr_nonnull
From: Matt Calabrese (rivorus_at_[hidden])
Date: 2013-10-04 13:38:00


On Fri, Oct 4, 2013 at 6:39 AM, Thorsten Ottosen <
thorsten.ottosen_at_[hidden]> wrote:

> The deleter thing can probably be handled with a consrtuctor like
>
> template< class D, class Args ... >
> shared_obj( D, Args args... );
>
> For stuff not allocated via new, it can be probably be handled by
> another version of make_shared_obj.

You pretty much need a separate sort of make_shared type of constructor for
this, as Andrey pointed out, otherwise you have ambiguity. Even if you make
the first parameter an explicit tag type when specifying a deleter, it
doesn't handle the case where the constructed object can also take that
parameter (I.E. a shared pointer to a shared pointer). I'm fine with a
named function.

There are other problems though, for instance, you are implying here that
new is used to allocate the object, which is not always the case. The
function that does the construction needs to be able to handle that case as
well. Even with that, this doesn't account for the use where the shared_ptr
is taking control of an already allocated object. In other words, let's say
you get returned a pointer from a function that's a part of an API which
does its own dynamic allocation and construction, which isn't uncommon. For
instance, a factory function returning a pointer to a base class. In this
case, the shared_ptr should not be explicitly calling the constructor at
all.

Almost all of these cases can be handled by named constructor-like
functions in a somewhat elegant manner, with the exception perhaps of the
last one (what happens if the factory function can return a null pointer?
We're back to the original issue, in that case, only worse because the
programmer cannot simply handle that case outside of the constructor). I
think ultimately my vote would be to support named functions, but there
still needs to be a way to do construction via a direct pointer otherwise
we are losing functionality that shared_ptr provides.

I'll repeat my basic, underlying stance here for people to agree/disagree
with. A non-null shared_ptr should be exactly that. It should have the same
or extremely similar interface to a shared_ptr (including things like
bool-conversion), just with more strict invariants and preconditions. This
makes drop-in replacement and use in generic functions easier to deal with
and also avoids sacrificing additional functionality that shared_ptr
provides. People shouldn't have to avoid switching to a non-null shared
pointer simply because they have no way of constructing it with a pointer
that they obtained from a factory.

-- 
-Matt Calabrese

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