Boost logo

Boost Users :

From: Frank Maddin (frankmad_at_[hidden])
Date: 2004-09-07 17:11:34


Ahh, so now I'm able to do such things as this.

                Hello* h_ptr = new Hello();
                World* w_ptr = new World();
                typedef boost::signal< int (int, float) > IntFloatSignal;
                IntFloatSignal sig;
                sig.connect(boost::bind(&Hello::alternate_int_float, h_ptr, _1, _2));
                sig.connect(boost::bind(&World::alternate_int_float, w_ptr, _1, _2));
                float temp = 0.0f;
                sig(1, temp);

> 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!)?

I guess I was thinking that since nothing is done with inheritance, it provides less opportunity to do things that might get you into trouble. If I've a hierarchy that looks something like this:

        BaseObject
        SimpleObject : BaseObject, signals::trackable
        ComplexObject : SimpleObject
        ReallyComplexObject : ComplexObject, signals::trackable

where a SimpleObject can get a signal of one type and a ReallyComplexObject object can get another, is trackable inheritance ok with this or is there some other recommended method?

Thanks again,
Frank

-----Original Message-----
From: boost-users-bounces_at_[hidden] [mailto:boost-users-bounces_at_[hidden]] On Behalf Of Doug Gregor
Sent: Tuesday, September 07, 2004 2:38 PM
To: boost-users_at_[hidden]
Subject: Re: [Boost-users] signal slot flexibility

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 mailing list
Boost-users_at_[hidden]
http://lists.boost.org/mailman/listinfo.cgi/boost-users


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