Question

Without spending a long time reviewing the boost source code, could someone give me a quick rundown of how boost bind is implemented?

Was it helpful?

Solution

I like this piece of the bind source:

template<class R, class F, class L> class bind_t
{
public:

    typedef bind_t this_type;

    bind_t(F f, L const & l): f_(f), l_(l) {}

#define BOOST_BIND_RETURN return
#include <boost/bind/bind_template.hpp>
#undef BOOST_BIND_RETURN

};

Tells you almost all you need to know, really.

The bind_template header expands to a list of inline operator() definitions. For example, the simplest:

result_type operator()()
{
    list0 a;
    BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
}

We can see the BOOST_BIND_RETURN macro expands to return at this point so the line is more like return l_(type...).

The one parameter version is here:

template<class A1> result_type operator()(A1 & a1)
{
    list1<A1 &> a(a1);
    BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
}

It's pretty similar.

The listN classes are wrappers for the parameter lists. There is a lot of deep magic going on here that I don't really understand too much though. They have also overloaded operator() that calls the mysterious unwrap function. Ignoring some compiler specific overloads, it doesn't do a lot:

// unwrap

template<class F> inline F & unwrap(F * f, long)
{
    return *f;
}

template<class F> inline F & unwrap(reference_wrapper<F> * f, int)
{
    return f->get();
}

template<class F> inline F & unwrap(reference_wrapper<F> const * f, int)
{
    return f->get();
}

The naming convention seems to be: F is the type of the function parameter to bind. R is the return type. L tends to be a list of parameter types. There are also a lot of complications because there are no less than nine overloads for different numbers of parameters. Best not to dwell on that too much.

OTHER TIPS

By the way, if bind_t is collapsed and simplified by including boost/bind/bind_template.hpp , it becomes easier to understand like the following :

template<class R, class F, class L> 
class bind_t
{
    public:

        typedef bind_t this_type;

        bind_t(F f, L const & l): f_(f), l_(l) {}

        typedef typename result_traits<R, F>::type result_type;
        ...
        template<class A1> 
            result_type operator()(A1 & a1)
            {
                list1<A1 &> a(a1);
                return l_(type<result_type>(), f_, a, 0);
            }
    private:
        F f_;
        L l_;

};

I think it's a template class that declares a member variable for the arguments you want to bind and overloads () for the rest of the arguments.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top