Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2004-08-27 09:30:23


On Aug 27, 2004, at 8:44 AM, Peter Dimov wrote:

> Bronek Kozicki wrote:
>> Howard Hinnant wrote:
>>> template<class T, class D = typename detail::default_delete<T>::type>
>>> class move_ptr;
>> why in type? This could be stored in trampoline function, stored
>> together with pointer, something like this
>> http://b.kozicki.pl/cpp/ext_auto_ptr_090.zip
>
> So that sizeof(move_ptr<T>) can be the same as sizeof(T*).

Yes, yes! Absolutely zero-overhead over a raw pointer is (imho) a
critical design criteria of this type of smart pointer. And the reason
for the ::type dance instead of something more direct like:

template<class T, class D = detail::default_delete<T> >
class move_ptr;

is to support the array specialization:

template<class T, class D> class move_ptr<T[], D>;

The default argument in the primary template must serve both the
primary, and the array specialization. And you need different defaults
for those two cases. Thus the extra level of (compile time)
indirection.

Oh, I forgot to mention other criteria that I consider very important
concerning the deleter:

1. Clients should be able to get references to the embedded deleter (I
prefer both const and non-const):

     deleter_reference get_deleter();
     deleter_const_reference get_deleter() const;

2. And the deleter itself should be able to be a reference type.

I can't stress this second point enough. It is a real feature when you
want to allow for the possibility of a deleter that is both state-full
and heavy. In templated code that already owns a deleter (that you
don't know anything about, except its name), and you're using the
move_ptr just to enforce ownership temporarily (say for exception
safety purposes), then passing a reference-typed deleter to the
move_ptr is an extremely elegant solution:

Code templated on P (p : pointer type) and D (d_ : deleter type):

     move_ptr<P, D&> hold(p, d_); // grab hold of p, using a D&, as
opposed to a D
                                    // avoids copying the D, might do a
better job
                                    // of maintaining the state of d_.
                                    // This can't fail, even if D's copy
ctor might

     s_ = new ... p ... // acquire ownership of p - might
throw an exception
     hold.release(); // move_ptr's job is done, transfer
ownership to (s_,d_)

-Howard


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