Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2003-09-19 15:55:01


On Thursday 18 September 2003 07:58 pm, Edward Diener wrote:
> On the second issue: I acknowledge this at the bottom of my original post.
> Ideally it would be nice for the end-user to know that a particular
> connection refers to a particular handler. I am used to Borland's __closure
> where the member function handler can actually have its __closure address
> taken and compared against the actual address in the __closure pointer
> which represents the signal. Of course this is a simpler, less flexible
> system that does not do multi-cast events.

Well, you're not the only one that wants this capability :) Herb Sutter wrote
an article on function, and that was his main criticism/suggestion.

> If the boost::function, boost::bind concept will never allow the end-user
> to know what handler is actually bound to a boost::function after the fact,
> then the idea of user-defined ordering, where the two const boost::function
> references are passed at decision-making time, is worthless.

I don't know that boost::function ever will allow this... it's not technically
feasible in C++98/03, but who knows what will change in the next revision of
the language.

> OTOH, your suggestion above makes me think that a user-defined ordering
> might be at least conceivable if the lexigraphic function I originally
> described actually passed back to the end-user the group type values
> instead of const boost::function references. The group type values could
> also have, as an example, C++ member function pointers which would enable
> the end-user to determine which slot should be called first.

Yes, that could work.

> > The benefit of allowing both LIFO and FIFO ordering is that users get
> > more control over slot ordering. There may be uses where this is
> > absolutely necessary; I'm not sure.
>
> From you perspective is it really difficult programming ? It seems that
> once you have a FIFO queue for a given group, going backward through that
> queue is easy.

I'm not at all concerned about the implementation side... once FIFO is
implemented, LIFO is trivial. It just means that one inserts at the beginning
of a list instead of at the end.

> > The cost is that we will need more connect() overloads, and we'll
> > have some duplication in the slot interface: you can order slots via
> > group names and with fifo/lifo subgroup ordering. One could argue
> > that this completely redundant, because one can use a pair<group,
> > foo> instead of group slot ordering to achieve the same thing.
> >
> > Here's a counter-proposal, that I think captures most of the
> > semantics of your proposal. I'll note differences at the end:
> > 1) Connecting a slot without specifying a group name uses a
> > default-constructed group name.
>
> Group "value" instead of group "name" ? Name implies to me that you are
> specifying the group value as a literal.

Yes, perhaps that's better nomenclature.

> > 3) "user" in-group ordering doesn't exist (because I don't think it's
> > feasible from an implementation perspective)
>
> But the
> first time some programmer asks why he can't make the final decision just
> before the signal occurs, we can both smile.

:)

> > 4) "lifo" ordering doesn't exist, because I'm guessing it isn't work
> > the addition of more connect() overloads. This is the change for
> > which I have the least rationale.
>
> I agree with you on a practical level since I have never used a system,
> other than your current implementation, where fifo wasn't the rule. I do
> wonder if anyone has ever used a system where the last slot connected is
> the first to be signalled. It does seem to me that the overhead for this is
> merely a very slightly more complicated and less elegant interface.

My concern is only the complication of the interface. Every new overload
brings additional complexity. We now have:

        connect(group, slot)
        connect(slot)

We're definitely adding:

        connect(front_or_back, slot)

If we add the ability to use LIFO or FIFO, we add three more overloads:

        connect(group, slot, ifo)
        connect(slot, ifo)
        connect(front_or_back, slot, ifo)

I can just imagine the naive user trying to figure out where on each this
connects a slot:
        connect(at_front, slot, lifo)

or, the difference between:

        connect(slot, fifo)

and

        connect(at_back, slot);

The two mechanisms---front/back of the group ordering vs. front/back within
the group---are just too close together, and it's bound to cause confusion.

I guess I'm just leary of adding more customizability without very strong use
cases. I've done that before, and had to back out the changes *cough*
function policies *cough*.

        Doug


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