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