$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.