
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] 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:
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