Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-02-26 19:09:31


On Tuesday 26 February 2002 06:35 pm, you wrote:
> In any case, here's my
> justification:
>
> From the point of view of a combiner, the sequence of slot calls is merely
> a sequence of values. We already have a concept that describes a sequence
> of values: an input iterator sequence. By reusing that concept, we are
> automatically able to reuse any operation defined on input iterator
> sequences, and the STL is full of those.
> <<------------------------------------------------------
> But is this really the case? That the signal will/should only be sent once?
> That the result can be considered a "value", and not that the act of
> calling the function is the effect we are looking for?

I think that the effect that we're looking for is the function call. However,
function calls return values, and we need to deal with those values in some
way. Input iterators provide a standard interface to dealing with sequences
of values, and we can leverage preexisting code by using this interface.

I think that each slot should only be called once, even when the iterator is
dereferenced multiple times. But aside from my personal feelings on this, I
believe that it is required behavior of operator* for an input iterator. A
while back I asked a similar question, which boiled down to "is the result of
dereferencing an input iterator stable"? After some discussion, I _think_ we
came to the agreement that input iterator dereferencing is (or should be)
defined as a stable operation. The argument that clenched it for me:
std::find() would be useless on an input iterator if the result of
dereferencing the input iterator is not stable, because dereferencing the
iterator you get back from find could give you a different result than what
find() just found. If you buy this 'dereferencing must be stable' argument,
and that input iterators are a good way to represent the values to be
combined, then it is required thatslots be called only once per signal
invocation. The thread I'm discussing starts here (note that my max_element()
example is incorrect, but find() would be correct):

  http://groups.yahoo.com/group/boost/message/14090

> I may be really confused here. But I'd like to become enlightened. Does
> anyone
> who has used the Signal/Slot concept in production code care to chime in
> on this?
>
> (Also note: this is an implementation detail AFAIK, and maybe I'm
> complaining
> about things that are really better left up the author of the library. It's
> just that at first look at the code, it's not obvious what *iter is doing.
> And
> as a maintainer of other people's code I prefer to have things like this
> stand
> out a bit more so I don't mess it up, rewriting things that shouldn't be
> touched)

It really isn't an implementation detail, though. Any user that wants to use
their own combiner will have to use this input iterator-based interface, and
we should make sure it is an appropriate interface. Personally, I see input
iterators as the only pre-existing, established interface to perform this
task. Other signal/slot libraries that allow combining of return values have
special interfaces to handle the slot calling; I think the strength of the
input iterator-based approach is that it uses a common interface technique,
so there is very little new knowledge one needs to use it.

> >> ==========================
>
> New Statement:
> Let me also chime in that I think that order of signaling
> can be very important to some applications. And that it would
> be good for the user of the library to be able to specify, FIFO, or
> LIFO for signal handlers.

We've seen a lot of requests for ordering, and it is definately on the TODO
list. We should discuss further how to meet user's needs in this area.

        Doug


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