$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Larry Evans (cppljevans_at_[hidden])
Date: 2006-08-31 17:28:06
On 08/31/2006 03:07 PM, Paul Mensonides wrote:
>>-----Original Message-----
[snip]
>>>smart pointer so that it doesn't require a double
>>>allocation.)
>>
>>I assume you mean one which doesn't use an intrusive 
>>refcount, IOW, uses a "detached" refcount like the existing 
>>shared_ptr? IOW, with the current shared_ptr, an one 
>>allocation is for the pointed-to object, the other is for the 
>>refcount. 
> Yes, basically you have the smart pointer allocate the
> pointed-to-object itself as a data member of a struct that also
> contains the reference count.  E.g.
 
> template<class T> class smart_ptr {
>     // ...
>     private:
>         struct data {
>             unsigned long rc;
>             T value;
>         } * p_;
>         smart_ptr(data* p);
> };
> You need a forwarding contructor on the 'data' structure to directly
> initialize the 'value' member.  You also need a forwarding function
> on whatever takes the arguments from clients--so the resulting
> syntax looks something like:
 
> smart_ptr<X> p = make_ptr<X>(a, b, 123);
> The make_ptr<X> function has to construct a 'smart_ptr<X>::data'
> object and initialize a smart_ptr with it and return that smart_ptr.
The above make_ptr<X> is close to the managed_ptr::
auto_overhead<X,ulong_rc> where: 
  template<class>
  struct ulong_rc
  {
      unsigned long rc;
  };
and instead of:
  smart_ptr(data* p)
  
there would only be:
  smart_ptr(auto_overhead<T,ulong_rc>& a_auto)
  
IOW, auto_overhead is simply derived from auto_ptr with the pointee
being an instance of the managed_ptr::
overhead_referent_vals<ulong_rc,T>.  IOW,
overhead_referent_vals<ulong_rc,T> corresponds to your 
smart_ptr<T>::data.  The reason for the elaborate overhead_referent_*
classes is to allow different smart_ptr policies, e.g. to allow strong
and weak pointers.  The reason for disallowing:
   smart_ptr(overhead_referent_vals<ulong_rc,T>*)
   
is to never expose a raw pointer to the client.   
> One problem of forwarding is arity (which can be more-or-less solved
> with code generation).  The more stubborn problem with forwarding is
> temporaries.  They cannot be bound to a non-const reference, and the
> template mechanism cannot deduce T as const U in a parameter of type
> T&.  OTOH, non-temporaries don't have any problem deducing T as U or
> const U in a parameter of type T&.
Yeah, I had that problem which is why the a_auto above is not 'const &'.
I remember some attempt at a workaround, but can't remember the
details or even if it worked.
> Unfortunately, the only way to handle it transparently is to
> overload via cv-qualifier--which leads the the combinatorial
> explosion when multiple parameters are involved.
:(
> 
>>the workaround implemented with the help of 
>>managed_ptr_ctor_forwarder.hpp:
>>
>>  http://tinyurl.com/o7zlg
>>  
>>generates CTOR's of the form:
>>
>>    template
>>    < class VecOfTypes
>>    >
>>  ctor_this_type
>>    ( VecOfTypes const&
>>    , mpl::at_c<VecOfTypes,0>::type a0
>>    , mpl::at_c<VecOfTypes,1>::type a1
>>    , ...
>>    , mpl::at_c<VecOfTypes,n>::type an
>>    )
>>    : ctor_base_type
>>      ( a0
>>      , a1
>>      , ...
>>      , an
>>      )
>>    {}
>>
>>IOW, the client has to specify the "signature" of the 
>>ctor_base_type CTOR via a single VecOfTypes template arg to 
>>the ctor_this_type CTOR.  The justification for this was that 
>>the client would have to know which ctor_base_type CTOR he 
>>wanted anyway, so it would not be that much of a burden for 
>>him to name it, indirectly, by supplying the "signature".
> 
> I'm not sure why you need to add this into each class (rather than
> just to the smart-pointer-related interfaces).
Sorry I was unclear.  This above is only needed for the auto_overhead
class. IOW, replace ctor_this_type with auto_overhead and
ctor_base_type with Referent from auto_overhead<Referent,Overhead>.
Of course it's a little more complicated, but that's essentially
what's happening with the MANAGED_PTR_CTOR_FORWARDER_OVERLOAD macro
invokation in the middle of the auto_overhead class definition.
> It may be that we're not talking about the same thing, but the
> smart_ptr facilities above could be designed without *any* intrusive
> requirements on the type pointed-to
Likewise, auto_overhead does not have *any* intrusive requirements
since the only allocation is for
overhead_referent_vals<ulong_rc,pointee_type>.
> and without *any* manual listing of argument types by the client.
> Granted, you can only support a fairly low number of parameters
> (larger if you ignore volatile).
 
And this, AFAICT, is the advantage of make_ptr vs. auto_overhead.
IOW, auto_overhead does have to supply, as mentioned in my previous
post, the signature (VecOfTypes in the above code) of the desired
"target" CTOR.