
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Paul Mensonides
Revisions inline...
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:
Actually, you only need combinatorial forwarding on the function that takes arguments from the client. You don't need it elsewhere because then you don't have temporaries.
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.
Given the above, you could solve (i.e. avoid) the combinatorial problem by linearizing the input. If you have no temporaries, you can just use T& and T will bind correctly to a cv-qualified type. To get rid of temporaries (which can't bind to T&) you need: template<class T> inline T& identity(T& x) { return x; } template<class T> inline const T& identity(const T& x) { return x; } template<class T> inline volatile T& identity(volatile T& x) { return x; } template<class T> inline const volatile T& identity(const volatile T& x) { return x; } What was called before as f(a, b, c); can be called as f(identity(a), identity(b), identity(c)); ...which is relatively easily generated via the preprocessor--especially with variadic macros: F(a, b, c) -> f(identity(a), identity(b), identity(c)) Without variadic macros, you'd have to specify the number of arguments or do something like: F((a)(b)(c)) Regards, Paul Mensonides