STL中的binder

 1 #include <functional>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 int main(int argc, char *argv[])
 7 {
 8     binder1st<greater<int> > big = bind1st(greater<int>(), 3);
 9     int value = 4;
10 
11     if (big(value))
12     {
13         cout<<"Greater than "<<value<<endl;
14     }
15     else
16     {
17         cout<<"Not Greater than "<<value<<endl;
18     }
19 
20     return 0;
21 }

见上面实用STLbinder的实例代码,其中关键是

1 binder1st<greater<int> > big = bind1st(greater<int>(), 3);

这一句,其中拆开来,是由以下几个部分组成

greater<int>()是将greater<int>::operator()传给bind1st()(之前错误以为是构造了一个临时的对象,纠正一下!!!)
binder1st<greater<int> > big是定义一个binder1st对象,用于保存bind1st()返回的binder1st对象,该对象即是对greater<int>::operator()绑定第一个参数之后获得另一个functor。
由于greater是binary_function,本身有2个入参,如此绑定之后获得第一个如参就被固定成bind1st()第二个参数中给的值(这里是3),那么调用big(value),就相当于调用greater<int>(3, value),即达到绑定的作用

如此理解了STL binder的实用方法之后,进一步剖析一下binder的实现,以bind1st为例,其定义很简单,如下

1 template<typename _Operation, typename _Tp>
2 inline binder1st<_Operation>
3 bind1st(const _Operation& __fn, const _Tp& __x)
4 {
5   typedef typename _Operation::first_argument_type _Arg1_type;
6   return binder1st<_Operation>(__fn, _Arg1_type(__x));
7 }
 1   template<typename _Operation>
 2     class binder1st
 3     : public unary_function<typename _Operation::second_argument_type,
 4                 typename _Operation::result_type>
 5     {
 6     protected:
 7       _Operation op;
 8       typename _Operation::first_argument_type value;
 9 
10     public:
11       binder1st(const _Operation& __x,
12         const typename _Operation::first_argument_type& __y)
13       : op(__x), value(__y) { }
14 
15       typename _Operation::result_type
16       operator()(const typename _Operation::second_argument_type& __x) const
17       { return op(value, __x); }
18 
19       // _GLIBCXX_RESOLVE_LIB_DEFECTS
20       // 109.  Missing binders for non-const sequence elements
21       typename _Operation::result_type
22       operator()(typename _Operation::second_argument_type& __x) const
23       { return op(value, __x); }
24     }

 bind1st第一个参数是一个仿函数对象,就比如functional里预定义的greater、plus之类的binder系列类,这些类都是继承了

 1   template<typename _Arg1, typename _Arg2, typename _Result>
 2     struct binary_function
 3     {
 4       /// @c first_argument_type is the type of the first argument
 5       typedef _Arg1     first_argument_type; 
 6 
 7       /// @c second_argument_type is the type of the second argument
 8       typedef _Arg2     second_argument_type;
 9 
10       /// @c result_type is the return type
11       typedef _Result     result_type;
12     };

这些仿函数类中都因此有了first_argument_type、second_argment_type和result_type的类型定义,而STL的binder即是利用这些预定义的类型。所以当需要自己定义给STL binder使用的仿函数类时,就必须继承binary_function以满足binder的需求。

==================================

现在发现boost/tr1的bind/function更为强大,好用!!!!——2014-03-27

原文地址:https://www.cnblogs.com/lanyuliuyun/p/3013376.html