Boost logo

Boost :

From: Jesse Jones (jesjones_at_[hidden])
Date: 2001-05-07 17:55:11


>Let me try again :) By building the timer interface so that it
>requires callback comparisons, you are effectively restricting the use
>of the timer so that only callbacks can be used with it. I don't have
>any wonderful examples at the moment, but perhaps you need to ping a
>certain address every 100ms. Personally, I would create a 'ping'
>function object that takes the address and send an instance of 'ping'
>to the timer. Why should I implement operator== just so that I can use
>a timer? I think such an interface is overly restrictive.

You're right: that's not a wonderful example. :-) But if you want to
have a functor get time it'll work fine. The only annoyance is that
you have to define operator==. That's not great, but it doesn't
restrict you in any real way.

>I'm looking at an interface more like:
>class ITimer {
> TimerHandle AddTimer(const function<void>& f, int ms, ...);
> void RemoveTimer(TimerHandle handle);
> void SetDelay(TimerHandle handle, int ms);
>};
>
>This interface doesn't require comparisons between function objects,
>so if I've constructed a function object to give to the AddTimer
>routine I don't have to reconstruct it (or keep it around) to give to
>the constructor.

Sure, you return a cookie used to identify the timer. But if you make
the reasonable requirement that you can't install multiple timers
on one callback you can ditch the cookie. I don't think it buys you
anything: it's just one more piece of data for users to juggle.
Whereas with my approach you can create a new callback whenever you
need to interact with the timer.

And the situation is worse for the menu commands. I have one
relatively small app that installs 46 callbacks to handle document
related commands. I certainly don't want to keep 46 cookies around...

> > >I'm almost wondering if there really is a fundamental difference
>between the
>> >two domains or if the lack of tools to enable the use of the
>"functor" domain
>> >in C++ is the cause of the difference. If the binder and lambda
>libraries
>> >were generally available and understood, would we be so reliant on
>the
>> >standard callback types, to functions and member functions?
>>
>> Here are the bulk of the places I use callbacks: to respond to
>> clicking on controls, to handle Undo/Redo (using the Command
>> pattern), to handle document state notifications (instead of the
>> Observer pattern), to respond to key events, to respond to menu
>> commands, to enable menu items, to get time, to allow users to
>> install custom error handlers , to specify the entry point and error
>> handlers for a thread, to support thread IOUs (aka futures), and to
>> call a callback for each node in an IHierarchy with an optional
>> predicate callback (this is normally the app, documents, windows,
>and
>> controls).
>
>I wonder if many of these GUI-centric uses of callbacks would better
>be suited for a signals/slots system, and if this would reduce the
>need for operator==.
>

Good question, but I don't know enough about signals/slots to have an
informed opinion...

> > Of all of these only the last seems the sort of thing the lambda
>> library is good for. Timers, document notification, key handlers,
>and
>> the menu handlers all rely on comparing callbacks.
>>
>> >I think that requiring operator== of every function object is too
>> >restrictive: standard library function objects don't support it,
>and likely
>> >neither will functors created by boost::bind or the lambda library,
>which
>> >will create a big hassle for users.
>>
>> I certainly don't like it, but when you're in the functor domain you
>> can often get by with using an anonymous functor. And clients can
>add
>> operator== functions easily enough...
>>
>> -- Jesse
>
>Easily, yes, but what a nuisance if you never intend to compare
>function objects. We shouldn't have users paying for what they don't
>use, especially when it requires extra work on their part NOT to use
>something.

I don't disagree with you, but it doesn't look like we're going to
get a design that's going to satisfy everyone. So, where do you make
the tradeoff?

   -- Jesse


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