
On 9/17/07, Tobias Schwinger <tschwinger@isonews2.com> wrote:
Try plugging your function object into boost::unfused_generic.
Hi Tobias, I have found a solution this way (and it works): These are the overloads according to the number of arguments (I just show 2 of them) template<typename T1> static Base* object(detail::KeyRef nm, T1 a1) { typedef boost::fusion::vector<T1> Args; typedef typename detail::tie_sequence<Args>::type Values; Values v(boost::fusion::vector_tie(a1)); return detail::Dispatcher<Base>::instance().template doObject<Values, Args>(nm, v); } template<typename T1, typename T2> static Base* object(detail::KeyRef nm, T1 a1, T2 a2) { typedef boost::fusion::vector<T1, T2> Args; typedef typename detail::tie_sequence<Args>::type Values; Values v(boost::fusion::vector_tie(a1, a2)); return detail::Dispatcher<Base>::instance().template doObject<Values, Args>(nm, v); } Then this is the _only_ inner common functions that is called by all the overloads: template<typename Values, typename Args> Base* doObject(KeyRef nm, Values& v) const { Range r; if (!find_range<Args>(nm, r)) return NULL; /* no function with the same number of arguments */ const SignatureClass<Base, Args>* p = find<Args>(r); if (p) return (*p)(v); /* perfect match found */ return NULL; } And finally this is the functor wrapper from which the operator() is invoked: /* 'FactoryClass' is subclassed from 'SignatureClass' and stores * the functor object used to create the requested object, * will be called due to dynamic polymorphism */ template<typename Base, typename Args, typename Functor> struct FactoryClass: public SignatureClass<Base, Args> { typedef typename tie_sequence<Args>::type Values; typedef typename Functor::result_type result_type; FactoryClass(const Functor& fn) : _functor(fn) {} virtual result_type operator()(Values& v) const { return boost::fusion::invoke_function_object(_functor, v); } Functor _functor; }; Where the base SignatureClass is: /* 'SignatureClass' is subclassed from StorableType and identifies * an unique argument list type (without return value). Used by * runtime argument checking */ template<typename Base, typename Args> struct SignatureClass : public StorableClass { // at runtime values passed to operator() are stored // in a tied vector, so set the signature accordingly typedef typename tie_sequence<Args>::type Values; virtual Base* operator()(Values&) const = 0; }; That is derived from the argument agnostic, storable in a map, base class: /* 'StorableType' is the common base class to store pointers * to different type of creators, dynamic_cast<> at runtime * will be used to check the (hidden) derived type */ struct StorableClass { virtual ~StorableClass() {} }; BTW I studied your factory and also your suggestion to use a map as a dispatcher to create a complete object factory from your one. The problem is that the classes must be registered at instantation time. IOW your factory (+ a map framework to act as dispatcher) does not seem to support the concept of adding new classes at runtime, everything must be already known at instantation/definition time. Please correct me if I'm wrong. Thanks Marco