From: Jiang on
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
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
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
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
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! ]

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