Prev: bind guard ?
Next: Sanity check: public/private
From: Jiang on 28 Aug 2006 12:26 Scott Meyers wrote: > 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. > Yes, Boost.Singals can replace Boost.Function most of the time, my list was intended to compare Boost.Function with old style callbacks. > > 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. > Well, actually the Solt part of the Boost.Signals is just a container which manages a list of function objects. And iterator based on quite a few iterator adaptors is available for iterating through the connected function objects in the container. The function objects are copyable, but Signals itself is noncopyable since the the connected slots are connected to signal, not the data member contained by signal object ( sorry for the wording here ). > > 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 :-) > Well, as you know, the Boost.Function is a quite small wrapper. It contains only two function pointers (invoker+manager) and one function pointer or data pointer. Also the dispatching through function pointer is very fast. Benchmark data is available at: http://www.boost.org/doc/html/function/faq.html#id2699504 However, the Boost.Signals asks more because it must manage the both the Signal and Slot(iterator), and the connection between them. Although the basic_connection holds several pointer members, and trackable must track all connections, I do not think memory space is really an issue. > > 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. > Exactly, I failed to find such a good example. :-) [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Hendrik Schober on 28 Aug 2006 12:21 Scott Meyers <usenet(a)aristeia.com> 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. For example, > http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Generalizing_ C-Style_Callbacks > describes the walk_tree function inside gcc, where the type of the callback > function is > > typedef tree (*walk_tree_fn)(tree *, int *, void *); > > This function pointer type is type-safe, though the void* parameter (used to > pass user-provided data) is not type-safe. IME that's (almost) always the case if you use functions. You need to provide some data for context to the callback. As what data is needed isn't known by the function calling the callback, a generic type is needed. I see only three choices for this: Passing around 'void*', making the function that calls the callback a template, or using (polymorphic) function objects. Using 'void*' is type-unsafe. That leaves templates and polymorphism. Since I can't turn every function into a template that takes a callback, polymorphism seems to be to the general solution to me. > [...] > Scott Schobi -- SpamTrap(a)gmx.de is never read I'm Schobi at suespammers dot org "The sarcasm is mightier than the sword." Eric Jarvis [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Chris Vine on 28 Aug 2006 18:05 Kurt Stege wrote: > From my page at http://www.goto.onlinehome.de/sigslot/sigslot.html > I have copied this list of references for signal slot libraries > that I am aware of. > > [Gregor2004]: Douglas Gregor > "Boost.Signals" > http://www.boost.org/doc/html/signals.html > This article discusses the signal implementation that is part of the > Boost libraries. > > [Hickey1994]: Rich Hickey > "Callbacks in C++ Using Template Functors" > http://www.tutok.sk/fastgl/callback.html > This old article describes a technical solution to call any member > function from a signal. > > [Thompson2002]: Sarah Thompson > "sigslot - C++ Signal/Slot Library" > http://sigslot.sourceforge.net/sigslot.pdf > http://sigslot.sourceforge.net/ > A typical signal-slot implementation using C++ templates. > > [TTL2005]: Eugene > "Tiny Template Library" > http://sourceforge.net/projects/tinytl > Template libraries that include a lightweight signal slot implementation > similar to the boost technology. > > [QT] The signal/slot library I generally use is libsigc++ at http://libsigc.sourceforge.net/ . Version 2.0 is not dissimilar to the boost signal library. Chris [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Scott Meyers on 29 Aug 2006 11:37 Jiang wrote: > Well, actually the Solt part of the Boost.Signals is just a > container which manages a list of function objects. You mean the signal here, not the slot, right? It's the signal that's a container, not the slot. > Well, as you know, the Boost.Function is a quite small > wrapper. It contains only two function pointers > (invoker+manager) and one function pointer or data pointer. Yes, but it also uses heap memory. So the total memory used by a boost::function object is more than just sizeof(boost::function<signature>). This is very important for some kinds of applications. > Also the dispatching through function pointer is very fast. It all depends on what you're comparing it to. In recent tests I've run, I've found invocation through a boost::function to be substantially slower than via a virtual call or a "delegate" (e.g., as in Don Clugston's FastDelegates library). I'm going to start a separate thread on this when I have time, because I was really surprised to find that invocation via boost::function was 2-3x slower than a virtual or delegate call. Currently, I'm hoping I did something stupid in my tests and that my data is invalid. (Yes, I compiled in release mode with full optimizations, but that doesn't mean I didn't do something else that's stupid, e.g., compare apples and oranges.) Scott [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Douglas Gregor on 2 Sep 2006 11:14
Scott Meyers wrote: > Jiang wrote: > > Well, as you know, the Boost.Function is a quite small > > wrapper. It contains only two function pointers > > (invoker+manager) and one function pointer or data pointer. > > Yes, but it also uses heap memory. So the total memory used by a > boost::function object is more than just sizeof(boost::function<signature>). > This is very important for some kinds of applications. Yes, and the cost of heap allocation when copying boost::function (or tr1::function) objects can also be costly in some applications. The latest boost::function (to be a part of Boost 1.34.0) uses a small buffer optimization to reduce the need for heap allocation, particularly in the common case where something like "bind(&X::f, &f, _1, _2, _3)" is placed into a boost::function. > > Also the dispatching through function pointer is very fast. > > It all depends on what you're comparing it to. In recent tests I've run, I've > found invocation through a boost::function to be substantially slower than via a > virtual call or a "delegate" (e.g., as in Don Clugston's FastDelegates library). > I'm going to start a separate thread on this when I have time, because I was > really surprised to find that invocation via boost::function was 2-3x slower > than a virtual or delegate call. > Currently, I'm hoping I did something stupid > in my tests and that my data is invalid. (Yes, I compiled in release mode with > full optimizations, but that doesn't mean I didn't do something else that's > stupid, e.g., compare apples and oranges.) What are you putting into the boost::function? Function objects? Member pointers? Function pointers? boost::function adds one level of indirection to whatever you put in there, so if you're comparing a boost::function calling through a function pointer against calling through the function pointer itself, expect a 2x difference because boost::function needs to perform two indirect calls through function pointers. Cheers, Doug [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |