
Hi Marco, On 9/6/07, Marco Costalba <mcostalba@gmail.com> wrote:
On 9/6/07, Dean Michael Berris <mikhailberis@gmail.com> wrote:
I'm looking for a similar solution, but more towards improving http://dispatcher.sourceforge.net/ to be able to support multiple function signatures in a single dispatcher instance. I think I've got a way to accomplish that with Boost.Fusion, but I doubt this same approach you propose will work for runtime determination.
Unless I'm missing something, in which case please enlighten me.
I studied your dispatcher code. The "trick" is that it supports only one signature per dispatcher. So that all the objects stored your maps could be easily derived form a base class with a given and fixed signature.
This is by design to enable coherent code which in place of a switch() {...} allows you to dispatch functions which are registered during runtime instead of just being statically defined at compile time. Consider how Boost.Signals does it by making it simple to have a homogeneous container of functions that got signalled when a message is passed to it -- only Boost.Signals is an excellent implementation of the publish-subscribe channel pattern, whereas the dispatcher is meant to be an implementation of a message router pattern.
When you want to store objects with different signatures in a single map you need (or at least I was not able to find something better ;-) to use a common base class with no signature information (StorableClass) and store pointers of that class, then you add signature info subclassing that class with a class templetized on a given signature (SignatureClass).
So you have a possible map:
map[(key1,p1) (key2,p2) (key3,p3) .... ]
where pointers
StorableClass *p1, *p2, *p3 are indeed pointers to objects of 3 different instances of a template<>SignatureClass
So pointers can coexist together also if the objects they point have different signatures. In the "simple_factory.hpp" example, I posted in a previous thread, a dynamic_cast at runtime is used to check the signatures hidden behind p1,p2,p3 against a given one.
The real problem is that two SignatureClass objects with different signatures:
SignatureClass<int (int,int)> and SignatureClass<int (int,double)>
HAVE DIFFERENT TYPE!!! so that a dynamic_cast is unable to discover that a set of values v1,v2 that could be used for the first one can be feed also to the second one.
Hope is clear...at least a bit ;-)
In this case, I think the approach I will take will be a bit more different that what you have chosen to do. Since I plan to do something like: void foo(int a) { ... }; void bar(int a, int b) { ... }; void foobar(int a, double b) { ... }; dispatcher< fusion::vector<void(int), void(int,int), void(int, double)> > d; d[0] = &foo; d[0] = &bar; d[0] = &foobar; If you look at the implementation(s) for the "functor" type in the dispatcher, it would be possible for it to provide the three operator() overloads following signatures given as a fusion::vector<> by containing three boost::function<>'s each having one signature, and having the deduction done during compile-time still. So that means: d[0](1); // foo() is called d[0](1, 2); // bar() is called d[0](1, 2.1); // foobar() is called This will be possible since the dispatcher's operator[] will return a reference to a 'functor' instance which overloads operator() following the many signatures it is configured to support. I think Boost.Fusion will definitely help in this extension through the fold<> algorithm/metafunction (for linear inheritance for the signature overloads). Although I'm not a Boost.Fusion expert, I'm pretty confident it's just a matter of sitting down and actually getting things to work the way I want them to work. I'm also right now (at least initially) convinced that this is actually feasible. ;) -- Dean Michael C. Berris http://cplusplus-soup.blogspot.com/ mikhailberis AT gmail DOT com +63 928 7291459