|
Boost Users : |
From: Doug Gregor (dgregor_at_[hidden])
Date: 2004-09-07 14:38:19
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<void (Hello*) > 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<void()> sig;
sig.connect(boost::bind(&Hello::alternate, &my_hello));
sig.connect(boost::bind(&World::alternate, &my_world));
> 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
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net