function object研究
_bi namespace 包含了boost的实现细节的代码。
先看一下list_av_1的定义:
// list_av_N
template<class A1> struct list_av_1
{
typedef typename add_value<A1>::type B1;
typedef list1<B1> type;
};
template<class A1, class A2> struct list_av_2
{
typedef typename add_value<A1>::type B1;
typedef typename add_value<A2>::type B2;
typedef list2<B1, B2> type;
};
这里看到add_value模板类,定义如下:
template<class T> struct add_value
{
typedef typename add_value_2< T, boost::is_placeholder< T >::value >::type type;
};
又用到了add_value_2,定义如下:
template< class T, int I > struct add_value_2
{
typedef boost::arg<I> type;
};
把事情连起来,还是要看一下调用代码:
// bind Foo function
vector<int>::iterator itor = std::find_if(v.begin(), v.end(),
boost::bind(Foo, _1));
template<class R, class F, class A1>
_bi::bind_t<R, F, typename _bi::list_av_1<A1>::type>
BOOST_BIND(F f, A1 a1)
{
typedef typename _bi::list_av_1<A1>::type list_type;
return _bi::bind_t<R, F, list_type> (f, list_type(a1));
}
在上一节的调用代码里面,_1被传递给了boost::bind函数。去掉宏的干扰,形如bind(Fun, _1)。
回顾一下_1是什么,其实就是boost::arg<1>类型的对象。这个对象没有任何成员,是表示第一个参数的占位符号。
然后,list_av_1<>模板收到这个boost::arg<1>这个模板参数后,又传给了add_value<>模板,
add_value<>利用is_placeholder<>模板获取到了boost::arg<1>中的1作为第二个模板参数(is_placeholder<>模板就是干提取值的事情),然后又将两个模板参数传递给了add_value_2<>模板。
add_value_2干了一件让我诧异的事情,把1又放回到boost::arg<>中,并且定义了等价类型add_value_2::type来代表boost::arg<1>,而第一个模板参数T被直接忽略。
所以add_value 最后得到的就是boost::arg<1>的等价类型type.
也就意味着list_av_1::B1 其实就是boost::arg<1>类型
比较复杂的在于typedef list1<B1> type这段类型定义,表面上看是在编译时推导出了类似list<arg<1> >这样的类型。
后面会继续挖掘如何实现的。
补充:综合编程 , 其他综合 ,