loop_in_codes

低调做技术__欢迎移步我的独立博客 codemaro.com 微博 kevinlynx

分析stl function objects模块


从SGI的STl文档来看,STL functor(function object)模块主要分为两个部分:预先定义的functor
以及functor adaptors。除此之外,为了使客端程序员写出适用于functor adaptor的functor,STL
又定义了一系列基本上只包含typedef的空类型(例如unary_function)。用户只需要派生这些类,即
可让自己写的functor被functor adaptor使用。以下称类基类型为base functor。

base functor包括: unary_function, binary_function,分别表示只有一个参数的函数和有两个参数
的函数。实际上STL里还有一个所谓的generator,代表没有参数的函数。因为STL泛型算法一般最多
只会使用两个参数的函数,所以这里并没有定义更多参数的base functor。

可被functor adaptor使用的functor又称为adaptable function,根据参数的个数,会被命名为诸如
adaptable unary function, adaptable binary function。

一个返回值为bool的functor又被称为predicate,可被用于functor adaptor的predicate被称为
adaptable predicate。其实所谓的adaptable,只需要在类型内部typedef一些类型即可,一般包括
first_argument_type, second_argument_type, result_type。functor adaptor会使用这些定义。

预定义的functors都是些很简单的functor,基本上就是封装诸如plus, minus, equal_to之类的算术
运算,列举一个predefined functor的代码:
 

template <class _Tp>
  
struct plus : public binary_function<_Tp, _Tp, _Tp>
  
{
     _Tp 
operator()(const _Tp& __x, const _Tp& __y) const   
     

         
return __x + __y; 
     }
    
  }
;


因为从binary_function(即我所谓的base functor)派生,因此这些predefined functor也是adaptable
function。

functor adaptors里有很多有趣的东西,其实functor adaptor也是一些functor(从SGI的观点来看,一般
的C函数,函数指针都算作functor)。所不同的是,他们通常会适配(adapt)一种functor到另一种。例如:
std::binder1st,严格地说它是一个函数模板,它会把一个adaptable binary function转换为一个
adaptable unary function,并绑定一个参数。又如: std::ptr_fun,它会将一个只有一个参数的C函数
适配成一个pointer_to_unary_function的functor。

下面列举一些具体的代码:
关于base functor,基本上就只有unary_function, binary_function :
 

template <class _Arg, class _Result>
  
struct unary_function
  
{
      typedef _Arg argument_type;                    
      typedef _Result result_type; 
  }
;
  


关于predefined functor,如之前列举的plus一样,再列举一个:

template <class _Tp>
 
struct greater : public binary_function<_Tp, _Tp, bool>
 
{      
     
bool operator()(const _Tp& __x, const _Tp& __y) const
     

         
return __x > __y; 
     }
    
 }
;

 
关于functor adaptors,也是我觉得比较有趣的部分,多列举几个:

template <class _Operation, class _Tp>
  inline binder1st
<_Operation>
  bind1st(
const _Operation& __fn, const _Tp& __x)
  
{
      typedef typename _Operation::first_argument_type _Arg1_type;
      
return binder1st<_Operation>(__fn, _Arg1_type(__x));
  }

  

 
bind1st返回的binder1st定义为:

 template <class _Operation>
  
class binder1st : public unary_function<typename _Operation::second_argument_type, 
  typename _Operation::result_type
>
  
{
  
protected:
      _Operation op;
      typename _Operation::first_argument_type value;
  
public:
      binder1st(
const _Operation& __x, const typename _Operation::first_argument_type& __y): 
        op(__x), value(__y) 
      
{}
      typename _Operation::result_type 
      
operator()(const typename _Operation::second_argument_type& __x) const
      

         
return op(value, __x); 
      }

     typename _Operation::result_type 
     
operator()(typename _Operation::second_argument_type& __x) const
     

        
return op(value, __x); 
     }

  }
;

 
值得一提的是,ptr_fun以及相关的pointer_to_unary_function, pointer_to_binary_function,基本上
就是用来绑定C函数的组件,不过这里采用了很基础的模板技术,因此只实现了绑定一个参数和两个参数
的C函数。这种组件类似于loki中的functor,以及boost中的bind,只是功能弱很多。与之相关的还有
mem_fun, mem_fun_ref, mem_fun1, mem_fun1_ref等,这些都是用于绑定成员函数的。另一方面,与其说
是绑定,还不如说适配,即将函数适配为functor(特指重载operator()的类)。( Mem_fun_t is an adaptor
 for member functions )采用这些(ptr_fun, mem_fun之类的东西)组件,客端程序员可以很容易地将各种
运行体(Kevin似乎很喜欢发明各种名字)(C函数、成员函数)适配成functor,从而与STL泛型算法结合。
例如, SGI文档中给出的mem_fun例子:

 

struct B {
 
virtual void print() = 0;
}
;

struct D1 : public B {
 
void print() { cout << "I'm a D1" << endl; }
}
;

struct D2 : public B {
 
void print() { cout << "I'm a D2" << endl; }
}
;

int main()
{
 vector
<B*> V;

 V.push_back(
new D1);
 V.push_back(
new D2);
 V.push_back(
new D2);
 V.push_back(
new D1);

 for_each(V.begin(), V.end(), mem_fun(
&B::print));
}

 

 

注:以上分析基于dev-cpp中自带的stl,源代码见stl_functional.h。

 

 

posted on 2008-03-13 13:31 Kevin Lynx 阅读(2474) 评论(2)  编辑 收藏 引用 所属分类: c/c++

评论

# re: 分析stl function objects模块 2008-03-13 13:41 cppexplore

这个要顶!  回复  更多评论   

# re: 分析stl function objects模块 2008-03-14 12:41 梦在天涯

高!  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理