![]() |
Boost : |
From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2006-08-31 16:07:16
> -----Original Message-----
> From: boost-bounces_at_[hidden]
> [mailto:boost-bounces_at_[hidden]] On Behalf Of Larry Evans
> > Regarding what the generated code is doing (as opposed to what the
> > generator code is doing), the major problem with forwarding without
> > language support is that it is a combinatorial problem--rather than
> > linear. I.e. you really need various combinations of const and-or
> [snip]
>
> Ouch! Do you know of anyone working on a compiler to solve
> this forwarding problem?
I know this is one of the things being tossed around in the committee, but I
don't know the likelihood that of acceptance or if it has already been accepted.
Dave would know more.
> > In any case, it is still reasonable up to 5 parameters if you're
> > ignoring volatile. I know that Dave implemented this kind of
> > forwarding for an operator new workalike that returned a smart
> > pointer. (With perfect forwarding, you can design a
> reference-counted
> > 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. If so, then this is what I was trying to do with:
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.
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&.
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). 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 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).
Regards,
Paul Mensonides
Boost list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk