From: kanze on
Kurt Stege wrote:
> kanze wrote:
> > werasm wrote:

> >>Scott Meyers wrote:

> >>>Also, does anybody know where the name "slot" comes from in
> >>>this context?

> >>I think the name "slot" originates from the Qt GUI Framework.

> >>I would define the signal as the "callable entity" and the
> >>slot as the "executable entity". The lost exists at the
> >>execution sight, whereas the signal exists at the callsight.

> > I would avoid the word "signal", as it has other meanings in
> > C++ (and C). What's wrong with the classic terms event or
> > notifier, and handler or callback?

> "Handler" is a worthless term. What is the handler handling?
> Signals? Events? Messages? Fruits?

I know. But is the classical term. Normally with a qualifying
adjective, e.g. a notification handler.

In fact, observer seems to be the correct term in this case.

> "Callback" is misleading. The word (and the classic meaning)
> says: I am calling you now. Please do you call _me_ back
> sometimes later.

Later or immediately. I've heard the term used in both
contexts.

> The callback idea separates the sender and the receiver of a
> message in a way that the sender (at compile time) does not
> know anything about the receiver. However, the receiver knows
> about the sender for registration purpose.

The receiver must know about some place to register. Normally,
this will be some sort of event forwarder, I would think, or an
abstract fassade to a subsystem. The sender must also know
where to post the message.

> The signal slot idea separates registration from the receiver.

An event forwarder, in sum. The concept is widely used in
distributed systems and network management; in such contexts,
generally, the forwarder also discriminates as to who receives
what.

> The receiver does not have to know anything about the sender,
> neither in compile time nor in run time.

If by "sender", you mean the originator of the event, this is
the usual situation. In all systems I've seen (going back some
fifteen or twenty years), there has been some sort of
intermediary message dispatcher. In the earliest ad hoc
systems, it was called a dispatcher; in more formal contexts, an
event forwarding discriminator. I've never heard the word
signal applied to this, except in Qt, and I've never heard the
word slot applied to anything in a program, except in Qt.

> This separation helps to re-use the receiver for other
> application contexts, just by exchanging the "application"
> that does the registration (often called "connection" between
> sender and receiver).

Except that from what little I've seen of Boost.Signal, it
doesn't support filtering in any way. So basically, you need a
signal per event type and per generating object, which both
receiver and sender have to agree on. I'm not sure that,
without filtering, it is that useful.

> >>Slots are basically the callback that gets called in
> >>response to a signal (event).

> > An asynchronous callback, in sum. Or a handler.

> See about the term "handler"? You like to name the signal a
> handler, and now you are naming the slot a handler.

I don't particularly like the term, but it is the consacrated
term for whatever handles the event.

> I didn't find short and pregnant replacements for the terms
> signal and slot. Message sender or event receiver might do,
> but they sound clumsy. I suppose the terms signal and slot are
> used in a wide area for exactly this purpose, that the danger
> of confusion with Unix- or C-signals is small.

My complaint was precisely that they are recent inventions for
an old concept. In the case of Qt, I presume that they were
invented because Qt does things in such perverse way (using a
pre-compiler) that they felt the need for new terms. In the
case of a normal library component, like the Boost component,
introducing new terms for an old and widely known and used
concept is a cause of confusion, and nothing else.

--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Jiang on
Scott Meyers wrote:
> Jiang wrote:
> > And for callback, usually it means function pointer which
> > will be passed to OS or special function (qsort ...).
> > Compared with Observer, this method is ensentially
> > not type safe and usually introduces tight coupling.
>
> Your perspective on this is interesting. I agree that a callback is
usually
> a function pointer and that it is often a void*, but it would never have
> occurred to me that a callback was inherently type-unsafe.
> Function pointers themselves are type-safe, so it's just the use of
> a void* to hold such pointer that's not type-safe.


Since argument list is part of the function type, most of the callbacks
use the genetic C-style function pointer:

void (*f)(void*)

The problem is, as you said, the user-provided data is not type safe.
As we can not make sure the passed data can be used safely or not,
this method is essentially not type safe.

Here I by no mean say the function pointer itself is type-unsafe.
But a type safe pointer is not sufficient to construct a type safe
mechanism for this issue.


>
> > Delegate solves the problems of typesafe directly event dispatching a
> > nd Observer mainly decouple the one-to-many dependency.
> > The functionalites overlap but they are different tools for different
> > purposes. That is why we have both boost.function and boost.signal.
>
>
> Why, for example, do we need Boost.Function?
>

Short answer: Yes, Boost.Signal uses Boost.Founction.

Well, I think we need Boost.Function because:

1. The old style callback mechanism is not type safe.

2. We can control the return type and function signature in a
systematical manner.

3. We can use both free and member functions with it.

4. We can check empty target call.

5. Generalization with reasonable space&time costs.

>
> What functionality does it offer that Boost.Signal does not?
>

Well, if we limit the context to functionality/usage, then,

1. Signal is non-copyable, but copy and assignment are
available for Function.

2. disconnect is not necessary for function object
replacement.

3. Compared with Boost.Signal, it is slightly fast
and memory friendly.

4. Function does not require you link any library.

I must say this question is quite difficult for me to answer.
there are many other similar questions, such as:

- Why cond+mutex and semaphore co-exist in POSIX?
- Why don't make member functions virtual by default?
- What functionality does umbrella offer that car does not? :-)

The point is, to repeat myself, Boost.Function provides
generalized, type-safe message dispatching mechanism,
while Boost.Signal helps us decouple one-to-many
dependency by constructing a ready-to-use pattern framework.
They stay in different abstraction levels in my mind.

Please do correct me if I am wrong, or you feel something
strange. I really hope Doug Gregor can elaborate on this issue.
After all, he wrote these two nice libraries (incidentally?).


> Can't I always replace this,
>
> class Widget {
> public:
> typedef boost::function<RetType(ParamType)> CallbackType;
>
> explicit Widget(CallbackType f): func(f) {}
> void makeCall(ParamType arg) { func(arg); }
>
> private:
> CallbackType func;
> };
>
> with this?
>
> class Widget {
> public:
> typedef boost::signal<RetType(ParamType)> CallbackType;
>
> explicit Widget(CallbackType::slot_type f) { func.connect(f); }
> void makeCall(ParamType arg) { func(arg); }
>
> private:
> CallbackType func;
> };
>


Yes, I believe you can use both implementations for
the above Widget class.

But, the above replacement does not show me why
Boost.Function should be replaced with Boost.Signal.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Scott Meyers on
kanze wrote:
> Or inversely, what does boost::signal offer in addition to what
> boost::function offers? I'm not that familiar with
> boost::signal, but a quick glance at the doc didn't reveal the
> most important addition for this sort of use: the possibility of
> associating a filter with the callback, so that it will only be
> called in certain circumstances.

I'm no expert, but AFAIK, Boost.Signal has no such functionality. Unlike
Boost.Function (and tr1::function), however, it is possible to "connect"
multiple functions (actually callable entities) to a single signal,
which is why
I have this notion that a Boost signal can be thought of as a
"container" of
callbacks.

Scott

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Scott Meyers on
Jiang wrote:
> Well, I think we need Boost.Function because:
>
> 1. The old style callback mechanism is not type safe.

But slots in Boost.Signal are typesafe and can, I believe, replace
Boost.Function objects in most contexts.

> 2. We can control the return type and function signature in a
> systematical manner.

Ditto.

> 3. We can use both free and member functions with it.

Ditto.

> 4. We can check empty target call.

Boost.Signals offers the "empty" and "num_slots" member functions for this.
Note how this makes a signal look syntactically like a container.

> 1. Signal is non-copyable, but copy and assignment are
> available for Function.

I didn't realize this, thanks for pointing it out. The lack of these
functions
makes Boost.Signal look less like a container.

> 3. Compared with Boost.Signal, it is slightly fast
> and memory friendly.

Can you give me an overview? I have a vague idea of the implementation of
Boost.Function, my guess would be that a Boost.Signal would be
implemented as,
um, a collection of Boost.Functions :-)

> But, the above replacement does not show me why
> Boost.Function should be replaced with Boost.Signal.

I'm not suggesting that Boost.Function should be replaced, I'm just
trying to
better understand the differences. C++ has both arrays and single
objects, even
though an array of size 1 could be used in place of single objects.

Scott

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: kanze on
Scott Meyers wrote:
> kanze wrote:
> > Or inversely, what does boost::signal offer in addition to what
> > boost::function offers? I'm not that familiar with
> > boost::signal, but a quick glance at the doc didn't reveal the
> > most important addition for this sort of use: the possibility of
> > associating a filter with the callback, so that it will only be
> > called in certain circumstances.

> I'm no expert, but AFAIK, Boost.Signal has no such functionality. Unlike
> Boost.Function (and tr1::function),

That's my impression as well. Of course, since they take
boost::function as parameters, it wouldn't be difficult to
insert filtering there.

> however, it is possible to "connect" multiple functions
> (actually callable entities) to a single signal, which is why
> I have this notion that a Boost signal can be thought of as a
> "container" of callbacks.

A non-copiable container with a function interface which
automatically iterates over the elements.

--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5
Prev: bind guard ?
Next: Sanity check: public/private