Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-11-26 08:37:38


On Monday 26 November 2001 08:02 am, you wrote:
> I define two signals, and I want connect one to the other:
> signal2<void, int, int> sig1,sig2;
> sig1.connect(sig2);
>
> my compiler ( MSVC6.0 SP5 ) refuse to compile:

The source of the error here is that signals are noncopyable (i.e., no copy
constructor or assignment operator). Not that you could have known this
without digging through the source code, because I forgot to document it!

> so I add an function slot_sig to do so:
>
> void slot_sig( int x, int y, const signal2<void,int,int> &sig )
> {
> sig( x, y );
> }
>
> signal2<void, int, int> sig1,sig2;
> sig1.connect(bind(slot_sig,_1,_2,sig2));
>
> there is still an error:

This is still the same problem from above, where we can't copy a signal. The
actual copy is being performed by the Boost.Bind library, because in this
statement:
  sig1.connect(bind(slot_sig,_1,_2,sig2));

... Bind does not know that "sig2" should be stored by reference instead of
by value. The default (which is used here) is to store by-value, which
requires a copy. To explicitly tell Bind that you want it stored by
reference, use:
  sig1.connect(bind(slot_sig, _1, _2, ref(sig2)));

... and everything should work properly.

> My question is: Did I make mistakes? What is the right way to connect
> a signal to anther one?

There is no real solution in the Signals library yet, though there are
several possibilities:
  1) Make ref() smarter, so that one can use:
    sig1.connect(ref(sig2)).
    The advantage here is that _any_ function object can be passed as a
reference to any algorithm, so we can use stateful function objects wherever
we want using ref.

  2) Make signal smarter, so that one can use:
    sig1.connect(sig2);
    This just patches up syntax. It could work along with (1).

  3) Give signal a strange but usable copy constructor. e.g., a signal can be
either a full-fledge signal, or it can be a reference to another signal. A
copy construction builds a reference to the incoming signal. Then,
    sig1.connect(sig2);
    works. The benefit here is that signals can then be passed around as
   function objects by "value", though I do wonder if there are some surprises
  ahead for something like this.

I'm not sure which is the best option. The "correct" answer is probably
either (3), if we can convince ourselves that there are no nasty surprises;
or (1) and (2), so that ref() becomes generally useful and the syntax is
patched up to be something logical. The only remaining problem with (1) and
(2) is that a signal is still not really a function object (because it is
noncopyable), so one has to use ref(sig) for use with standard algorithms.

Any input is greatly appreciated. I've been debating this for a looong time.

        Doug


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk