
First of all a great thank-you (!!!) to Joel and the rest behind the development of fusion. It's solved so many tasks for me and made me write so little code the past months I probably shouldn't even get paid. database-abstraction, remote function invocation with async handlers, console/web interface invocation, etc.. It's changed my perception of effective programming to a complete new level. What before was a struggle with mpl, is now clean and easy. Ok, so to my humble problem. I'm constantly finding myself writing those overloaded functions like: ------------------ template<class A0, class A1, ....> void operator()(const A0& a0, const A1& a1, ...) const { do_something_very_clever(fusion_sequence_type(a0, a1, ...)); } ------------------ This is cumbersome and boring, and usually I just add the overloads when someone else needs it.. It's not always the case I can know beforehand to overload const T& or just T& also, but it depends on the use case. Anyways, my idea is to generate the correct overloaded operator()(...) by specializing on the size of the fusion sequence, instantiate the sequence with the parameters when invoked by client code, and then use CRTP downcast to invoke a function with the fusion sequence. This way I can do the job with my neat fusion sequence without client-code needing to mess with boost::fusion::tie and boost::ref etc, and I don't have to bother with the overloads. I guess an example would explain better than the above noise. Here's what a trivial multi-dispatch function would look like. I use function_types here to build my fusion sequence, but it could just as well have been some preprocessor enumeration dito instead. The overloading class selecting the overload is named to pack_args (attached). template<class Func> struct simple_signal : public pack_args < simple_signal const, typename boost::fusion::result_of::as_vector<boost::function_types::parameter_types<Func>
::type, void
{ typedef boost::function1<void, const sequence_type> function; template<class F> struct invoke { invoke(const F& f) : f_(f) {} void operator()(const sequence_type& seq) const { boost::fusion::unpack_args(f_, seq); } F f_; }; template<class F> void connect(const F& f) { m_functions.push_back(invoke<F>(f)); } // callback from pack_args. I agree this convention looks ugly, but it'll do for now.. void on_packed_args(const sequence_type& seq) const { for(std::list<function>::const_iterator i = m_functions.begin(); i != m_functions.end(); ++i) { (*i)(seq); } } private: std::list<function> m_functions; }; I can now use the above with simple_signal<void(int const, int const) > sig; sig(24, 54); // call all connected functions here.. If I have overlooked anything in fusion that would give me this functionality, please point me in the right direction and I'll be forever grateful :) Regards, Christian