Prev: bind guard ?
Next: Sanity check: public/private
From: kanze on 25 Aug 2006 07:59 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 25 Aug 2006 08:17 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 27 Aug 2006 08:34 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 27 Aug 2006 08:36 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 28 Aug 2006 08:45
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! ] |