Boost logo

Boost :

From: Zach Laine (whatwasthataddress_at_[hidden])
Date: 2006-10-23 14:03:17


I have been using Boost.Signals for a few years now, and I find that
the mechanism for connecting to member function slots to be a bit more
cumbersome than it needs to be. I have been using a set of headers
patterned after Boost.Signal's signal*.hpp and signal_template.hpp
headers that define overloads of a free Connect() function to make
things easier. These headers define two important varieties of
overloads, one for connecting to member functions, e.g. (simplified to
hardcoded 1-argument case for readability)

template <class C, class R, class T1, class T2, class Arg1>
inline
boost::signals::connection
Connect(boost::signal<R (Arg1), C>& sig,
        R (T1::* fn) (Arg1),
        T2 obj,
        boost::signals::connect_position at = boost::signals::at_back)
{
    return sig.connect(boost::bind(fn, obj, _1), at);
}

and one for connecting a signal to another in a forwarding
relationship, e.g. (again, simplified):

namespace detail {
template <class C, class R, class Arg1>
struct Forwarder1
{
    Forwarder1(boost::signal<R (Arg1), C>& sig_) : sig(sig_) {}
    R operator()(Arg1 arg1) {sig(arg1);}
    boost::signal<R (Arg1), C>& sig;
};
}

template <class C, class R, class Arg1>
inline
boost::signals::connection
Connect(boost::signal<R (Arg1), C>& sig1,
        boost::signal<R (Arg1), C>& sig2,
        boost::signals::connect_position at = boost::signals::at_back)
{
    typedef typename detail::Forwarder1<C, R, Arg1> Forwarder;
    return sig1.connect(Forwarder(sig2), at);
}

This allows easier use of connections:

class Foo
{
public:
    void Slot() {std::cout << "slot invoked" << std::endl;}
};
Foo foo;
boost::signal<void ()> sig1;
boost::signal<void ()> sig2;

Connect(sig1, sig2); // forwards sig1 invocations to sig2
Connect(sig2, &Foo::Slot, &foo); // implicitly generates the correct
boost::bind object

sig1(); // prints "slot invoked"

If there is interest, I can rework things slightly so that the code
fits in with the existing Boost.Signals code.

So, two questions:

Is there interest in having this friendlier interface added to
Boost.Signals? If so, should it be in the form of connect() free
functions, or overloads of signal.connect()?

Zach Laine


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