Boost logo

Boost :

From: Beman Dawes (bdawes_at_[hidden])
Date: 2001-11-21 21:07:35


Doug,

Nice explanation, rationale, and comparison to libsigc++!

Please add this to your docs. The C++ committee is very interested in both
rationale for design decisions, and comparisons to other libraries. So
even if it is just a copy of your raw message below, please to add it.

I think I'm going to start encouraging Boost developers to add a (possibly
empty) FAQ to docs right from the word go. That way there is a place to
put answers to questions as they come up.

Cheers,

--Beman

At 06:50 PM 11/21/2001, Douglas Gregor wrote:
>On Wednesday 21 November 2001 04:48 am, you wrote:
>> I'm sorry for possible off-topic, but could you please comment how your
>> work is related to libsigc++?
>
>I can give you a comparison 'to the best of my knowledge.' I've looked at

>the
>documentation and implementation of libsigc++ before, but have not used
it
>extensively.
>
>The libraries are quite similar on the surface - the connection and
signal
>classes from each have nearly identical interfaces; the SigC::Object
class
>is
>quite similar to the "bindable" class from Signals in that a user type
>derives from one of these classes to enable automatic connection lifetime

>management (which both libraries support).
>
>I'll try to describe the differences in greater detail:
>
>libsigc++ Marshallers vs. Signals Combiners
>-----------------------------------------------------
>Both of these entities perform the same function: when a signal calls
>multiple slots, there must be some way to take the return values of many
>slots and make it into a return value for the signal itself.
>
>The libsigc++ Marshaller interface looks like this:
> struct SomeMarshal
> {
> // both typedefs must be defined.
> typedef Type1 InType; // type returned by a slot
> typedef Type2 OutType; // type returned by the signal
>
> // Return final return code.
> OutType value();
>
> // Return value if marshaller does not get built
> static OutType default_value();
>
> // Captures return codes and returns TRUE to stop emittion.
> bool marshal(const InType&);
>
> SomeMarshal();
> };
>
>When a libsigc++ signal invokes its slots, it will essentially do this:
> Marshaller marshaller;
> while (slot = next_slot() && marshaller.marshal(slot(...)));
> return marshaller.value();
>
>The Signals Combiner interface looks like this:
>struct Combiner {
> typedef T result_type;
> template<typename InputIterator>
> T operator()(InputIterator first, InputIterator last) const;
>};
>
>When a Signals signal invokes its slots, it will do this:
>Combiner combiner;
>return combiner(first, last);
>
>There is no difference in the power or flexibility afforded by either
>option.
>However, I'll claim that the approach taken by the Signals library is
more
>natural within the context of C++: the act of calling the slots is merely

>the
>iteration through the input iterator sequence the combiner is given, and
the
>
>combiner itself is just a function object taking an input iterator range.

>Often, it's much easier to use an interface where you "pull" the data as
you
>
>want it: if you don't pull data from a slot, that slot won't be called,
so
>the equivalent of a libsigc++ marshaller returning "TRUE" from marshal()
is
>a
>return statement in a Signals combiner.
>
>It is, of course, a matter of preference, but I believe that a function
>object taking an input iterator sequence and returning a value is more
"in
>the spirit of C++" than defining a special interface for this same
>operation.
>
>Argument Binding
>---------------------
>Both libraries "allow" argument binding, and arguments bound in creating
>slots can be tracked so that when they die, connections involving them
are
>removed. The difference between libsigc++ and Signals is mostly
>philosophical: libsigc++ includes limited capability for binding
arguments,
>
>and can track objects bound in the manner. Signals, on the other hand,
does
>
>not do any argument binding. Instead, another binder library (e.g.,
>Boost.Bind or Lambda) will perform argument binding and there is a bound
>argument discovery interface used by Signals to find those arguments.
>
>This keeps Signals decoupled from binding, so as new binding libraries
>become
>available Signals can adapt to them without any internal changes.
libsigc++
>
>doesn't currently have this ability.
>
>What's a Slot?
>-----------------
>Signals has a much looser definition of a slot than libsigc++ does.
>libsigc++
>is relatively strict regarding what a slot is -- return and argument
types
>should match exactly with the signal, and if there is a difference one
must
>
>manually build an adaptor to the appropriate type.
>
>The Signals definition of a slot is the same as that of a target for
>Boost.Function -- anything such that parameters of the type taken by the
>signal can be passed to the slot, and the return value of the slot
converted
>
>to the type expected by the signal. Thus all adaption is done internally
>without user intervention.
>
>I'll claim that the looser definition is more appropriate for a few
>reasons:
> - It's silly to manually adapt because the signal takes an std::string
and
>
>the slot takes a const std::string&.
> - Manual adaptations clutter the code (other side of the coin: they
make
>conversions explicit -- my side of the coin: they make trivial
conversions
>explicit, too)
> - Generic libraries define interfaces in terms of expressions, not
types.
>
>So saying that we need a function object that takes two ints and returns
an
>
>float is uncommon: instead we say that we need the expression f(a, b) to
be
>
>convertible to a float when a, b are integers. Signals follows this
generic
>
>programming view more closely.
>
>I hope such a comparison was useful, and if there are any other details
of
>libsigc++ for which information about the Signals equivalent could be
>helpful, please do ask.
>
> Doug
>
>Info: http://www.boost.org Unsubscribe:
><mailto:boost-unsubscribe_at_[hidden]>
>
>Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/


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