On Sep 7, 2004, at 1:36 PM, Frank Maddin wrote:
If I add a function to both Hello and World, from the “Hello World” example, called alternate() and set up signals like so:
boost::signal
sig_h; boost::signal< void (World*) > sig_w;
sig_h.connect(boost::mem_fn(&Hello::alternate));
sig_w.connect(boost::mem_fn(&World::alternate));
I have to define two different signals since the object type is part of the signal definition. Is there an easy way to get a single signal to call the alternate() function of both Hello and World?
Without Hello and World being related (e.g., sharing a base class
declaring a virtual "alternate" function), I don't see a way. Still,
when you call these signals you have to know whether you have a "Hello"
in hand or a "World"; perhaps you wanted to store the "Hello" and
"World" objects within the signal, and pass it no arguments? For
instance,
boost::signal
I recently found this signal slot solution. http://www.codeproject.com/cpp/ElmueSignalsandSlots.asp
There is an extra level of indirection here, in that you define a slot that points to the function. I’d be interested to see what people on this forum think about this solution. If I understand things correctly, this solution doesn’t seem to fit into the categories listed in the “Choice of Slot Definitions” docs.
I don't see much benefit to extra (explicit) level of indirection here. Most slots are short bind expressions that don't ever need to be revisited, so it seems that it could be a bit challenging to determine where some slots should reside: always in the class containing the member function that is called (assuming one only uses member functions!)?
Also a general signal slot question. What are the main reasons why developers don’t use an inherited pure interface for every callback type? A signal would be a template class with a list of pointers to the interface and some methods to operate on the list. Not flexible enough?
You often want only one event out of five, so it's a pain to drop in all of the stubs needed to ignore the other events. Also, you don't get a choice of names to use: if the writer of the interface says it's "on_click", you must write a function named "on_click" even though you'd rather write something like "submit_current_query" that describes the action taken when the event fires, not the event itself (which is essentially irrelevant).
Doesn’t scale well to larger uses? Time spent calling virtual functions? I saw this in the boost signal docs that might apply - “the use of a large number of small adaptor classes containing virtual functions has been found to cause an unacceptable increase in the size of executables (polymorphic class types require more code than non-polymorphic types)”.
This is more of an implementation detail; using function pointers instead of virtual functions tends to reduce the amount of code generated for libraries such as Boost.Signals or Boost.Function. Doug