boost bind初步探究 (二)

2014-11-24 00:59:37 · 作者: · 浏览: 10
F f, L const & l): f_(f), l_(l) {}

#define BOOST_BIND_RETURN return
#include
#undef BOOST_BIND_RETURN

};

template 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
#undef BOOST_BIND_RETURN

};
模板参数R代表return type, F代表function type, L表示的是listN(list0,list1,list2,....),这个是关键啊。


至于bind_template.hpp,这个源代码也比较简单,主要是定义了operator () 的实现。


bind_t重载括号运算符,因此,bind_t可以像函数那样调用。而且,bind_t的operator()有N多个重载,分别对应的是不同的参数类型和参数个数。这使得我们可以用不同的参数调用bind_t的对象。


我们摘抄一个有一两个参数的括号重载,看看
[cpp]
.....
template result_type operator()(A1 & a1)
{
list1 a(a1);
BOOST_BIND_RETURN l_(type(), f_, a, 0);
}
....

template result_type operator()(A1 & a1, A2 & a2)
{
list2 a(a1, a2);
BOOST_BIND_RETURN l_(type(), f_, a, 0);
}
......

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

template result_type operator()(A1 & a1, A2 & a2)
{
list2 a(a1, a2);
BOOST_BIND_RETURN l_(type(), f_, a, 0);
}
......
f_就是函数指针,这个不用多说;l_是 L (listN)对象。


请注意,这里有两个listN出现:
一个是l_ 这是针对f_提供的参数列表,其中包含_1,_2,....这样的placeholder
一个是生成的临时变量 a, 这个是bind_t函数对象在调用时 的参数列表
之所以一直强调两个listN,是因为,奥秘就在listN这些个类中的。大家请记住这一点:一直存在两个listN对象。


listN的奥秘
bind_t对象的operator () 调用的是listN 的operator (),那么,整个实现,就在listN中,为了方便说明,我们以list2为例。


对list2的分析,我们只看3部分:
1. 类声明部分:
[cpp]
template< class A1, class A2 > class list2: private storage2< A1, A2 >
{
private:

typedef storage2< A1, A2 > base_type;

public:

list2( A1 a1, A2 a2 ): base_type( a1, a2 ) {}

template< class A1, class A2 > class list2: private storage2< A1, A2 >
{
private:

typedef storage2< A1, A2 > base_type;

public:

list2( A1 a1, A2 a2 ): base_type( a1, a2 ) {}
从这个定义,我们知道,它从storage2继承,storage2是什么?
[cpp]
template struct storage2: public storage1
{
typedef storage1 inherited;

storage2( A1 a1, A2 a2 ): storage1( a1 ), a2_( a2 ) {}

template void accept(V & v) const
{
inherited::accept(v);
BOOST_BIND_VISIT_EACH(v, a2_, 0);
}

A2 a2_;
};

template struct storage2: public storage1
{
typedef storage1 inherited;

storage2( A1 a1, A2 a2 ): storage1( a1 ), a2_( a2 ) {}

template void accept(V & v) const
{
inherited::accept(v);
BOOST_BIND_VISIT_EACH(v, a2_, 0);
}

A2 a2_;
};
从名字和定义上,我们就可以断定:storage2就是保存两个参数的参数列表对象。看来,storageN负责存储,而listN负责如何使用这些参数了。


2. operator[] 系列重载函数
[cpp]
A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
A2 operator[] (boost::arg<2>) const { return base_type::a2_; }

.....

template T & operator[] (_bi::value & v) const { return v.get(); }
.....

A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
A2 operator[] (boost::arg<2>) const { return base_type::a2_; }

.....

template T & operator[] (_bi::value & v) const { return v.get(); }
.....

我已经剔除了一些定义,只留下我们关系的定义。


这里面有两类定义,
针对 boost::arg<1>和boost::arg<2>定义的。其实就是针对_1, _2的定义,这个定义表明:如果是_1,那么,list2就返回存储的参数a1, 如果是_2,那么就返回存储的参数a2。这些参数,是上面我说的针对f_函数的参数;
针对_bi::value的定义。_bi::value就是对T进行简单封装的类型。这个定义仅仅是将value的值再取出来。
这两类定义,就是关键所在了。


3. operator()系列重载函数
[html]
....
template void operator()(type, F & f, A & a, int)
{
unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
}
....

....
template void operator()(type, F & f, A & a, int)
{
unwrapper