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