C++仿函数

根据SGI官方文档,仿函数也叫函数对象(Function Object, or Functor),定义就是任何可以像函数一样被调用的对象。一个普通的函数是函数对象,一个函数指针当然也是,广义上说任何定义了operator()的类对象都可以看作是函数对象。

最基本的函数对象概念包括Generator, Unary Function(一元函数), 和Binary Function(二元函数),分别可以f(),f(x),f(x, y)的形式调用。当然这个概念还可以推广到接受多于两个参数的ternary function。

返回bool类型的仿函数比较特殊,比如返回bool的Unary Function叫做Predicate(谓词),返回bool的Binary Function叫做Binary Predicate。

有两个概念需要区分:function objects(函数对象)和adaptable function objects(可适应的函数对象)。一般地说,虽然一个Function Objects对它的参数的类型有要求,但是操作符operator()可以重载,可以是模板,或者两者兼有。也就是说,没有准确地方法获得这个Function Objects的参数和返回类型的信息。但是一个Adaptable Function Objects必须以typedef的形式指定他的参数和返回值得类型。如果一个类型F0是Adaptable Generator,那么它必须定义F0::result_type。类似地,如果F1是Adaptable Unary Function,那么它必须定义F1::argument_type和F1::result_type。如果F2是Adaptable Binary Function那么它必须定义F2::first_argument_type,F2::second_argument_type和F2::result_type。STL提供了unary_function and binary_function以简化Adaptable Unary Functions and Adaptable Binary Functions的定义。

Adaptable Function Objects是非常重要的,因为他们可以被function object adaptors(函数对象适配器,用来操作和控制其它函数对象)使用。STL提供了许多function object adaptors,包括unary_negate,unary_compose和binary_compose,用来对函数对象进行组合。

最后,STL包括了许多不同的预定义的函数对象,包括算子(plus,minus,multiplies,divides,modulus和negate),算术比较(equal_to,not_equal_to,greater,less,greater_equal和less_equal),和逻辑操作(logical_and,logical_or和logical_not)。这样你就可以不用手动写新的函数对象而是用这些函数对象就可以组合出相当复杂的操作。

例子
将一个vector<int>用随机数填充。这里,一个函数指针就是一个函数对象。

[cpp] view plain copy print ?
  1. <span style="font-size: 18px;">    vector<int> V(100); 
  2.     generate(V.begin(), V.end(), rand);</span> 

按照绝对值大小排序一个vector<int>。这里,函数对象是一个用户定义的class类型。
[cpp] view plain copy print ?
  1. <span style="font-size: 18px;">    struct less_mag : public binary_function<double, double, bool> { 
  2. bool operator()(double x, double y) { return fabs(x) < fabs(y); } 
  3.     }; 
  4.  
  5.  
  6.     vector<double> V; 
  7.     ... 
  8.     sort(V.begin(), V.end(), less_mag());</span> 

对一个vector<int>进行求和。这里,函数对象是一个可以保存状态的用户定义类型。
[cpp] view plain copy print ?
  1. <span style="font-size: 18px;">    struct adder : public unary_function<double, void
  2.     { 
  3.       adder() : sum(0) {} 
  4.       double sum; 
  5.       void operator()(double x) { sum += x; } 
  6.     }; 
  7.  
  8.  
  9.     vector<double> V; 
  10.     ... 
  11.     adder result = for_each(V.begin(), V.end(), adder()); [3] 
  12.     cout << "The sum is " << result.sum << endl;</span> 

删除list<int>中所有大于100且小于1000的元素
[cpp] view plain copy print ?
  1. <span style="font-size: 18px;">    list<int> L; 
  2.     ... 
  3.     list<int>::iterator new_end =  
  4. remove_if(L.begin(), L.end(), 
  5.      compose2(logical_and<bool>(), 
  6.        bind2nd(greater<int>(), 100), 
  7.        bind2nd(less<int>(), 1000))); 
  8.     L.erase(new_end, L.end());</span> 

你可能感兴趣的:(C++仿函数)