boost bind在内部是如何工作的?

33

不需要花费很长时间审查boost源代码,有人能给我一个快速概述boost bind是如何实现的吗?

3个回答

25

我喜欢这段bind源代码:

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

};

基本上告诉你几乎所有你需要知道的。

bind_template头文件会扩展为一系列内联的operator()定义。例如,最简单的:

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

我们可以看到BOOST_BIND_RETURN宏在这里被展开为return,因此该行更像是return l_(type...)

这是一个参数版本:

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

这很相似。

listN类是参数列表的包装器。这里有很多深奥的魔法,我并不太理解。它们还重载了operator()调用神秘的unwrap函数。忽略一些编译器特定的重载,它并没有做太多事情:

// 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();
}

命名约定似乎是:F 是要绑定的函数参数类型。R 是返回类型。L 倾向于是参数类型列表。由于不少于九个重载是为了处理不同数量的参数,所以还有许多复杂因素。最好不要太过深究。


2
这对我来说似乎不简单...为什么需要 #define BOOST_BIND_RETURN return?为什么不直接使用 return? - user365268
我还是不明白。调用bind_t的构造函数是什么? - ThomasMcLeod
2
@Ha11owed 因为这样他们可以将头文件用于没有返回值的模板! - Marco M.

2

顺便提一下,如果包含boost/bind/bind_template.hppbind_t 就会被折叠和简化,更易于理解,如下所示:

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_;

};

0

我认为这是一个模板类,它声明了一个成员变量来绑定你想要绑定的参数,并重载了()来处理其余的参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接