$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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