函数对象 Function Objects

1. 概述

函数对象(Function Object),或者叫做仿函数Functor(这两个是同义词)是任何能够像函数一样被调用的对象。一个普通函数是一个函数对象,一个函数指针也是函数对象;更一般的讲,定义了()运算符的类的对象也是函数对象。

2. 描述

基本的函数对象的概念有Generator, Unary Function和Binary Function,它们分别表示对象可以这样调用f(), f(x)及f(x,y)。(这个列表可以很容易扩展到三元函数,甚至更多,但是实际当中,没有一个STL算法需要超过两个参数的函数对象。)STL中定义的其他关于函数对象的概念都是这三个概念的refinement。

返回bool类型的函数对象是一种重要的特例。任何返回bool类型的Unary Function被称作Predicate,返回bool类型的Binary Function被称作Binary Predicate。

There is an important distinction, but a somewhat subtle one, between function objects and adaptable function objects. [1] In general, a function object has restrictions on the type of its argument. The type restrictions need not be simple, though: operator() may be overloaded, or may be a member template, or both. Similarly, there need be no way for a program to determine what those restrictions are. An adaptable function object, however, does specify what the argument and return types are, and provides nested typedefs so that those types can be named and used in programs. If a type F0 is a model of Adaptable Generator, then it must define F0::result_type. Similarly, if F1 is a model of Adaptable Unary Function then it must define F1::argument_type and F1::result_type, and if F2 is a model of Adaptable Binary Function then it must define F2::first_argument_type, F2::second_argument_type, and F2::result_type. The STL provides base classes unary_function and binary_function to simplify the definition of Adaptable Unary Functions and Adaptable Binary Functions. [2]

Adaptable function objects are important because they can be used by function object adaptors: function objects that transform or manipulate other function objects. The STL provides many different function object adaptors, including unary_negate (which returns the logical complement of the value returned by a particular AdaptablePredicate), and unary_compose and binary_compose, which perform composition of function object.

Finally, the STL includes many different predefined function objects, including arithmetic operations (plus, minus, multiplies, divides, modulus, and negate), comparisons (equal_to, not_equal_to greater, less, greater_equal, and less_equal), and logical operations (logical_and, logical_or, and logical_not). It is possible to perform very sophisticated operations without actually writing a new function object, simply by combining predefined function objects and function object adaptors.

3. 例子

用随机数填充一个vector。在这个例子里面,函数对象就是一个函数指针。

   1     vector<int> V(100);
   2     generate(V.begin(), V.end(), rand);

按照绝对值给double型的vector排序,也就是说忽略元素的符号。在这个例子里面,函数对象是是一个自定义类的对象。

   1     struct less_mag : public binary_function<double, double, bool> {
   2         bool operator()(double x, double y) { return fabs(x) < fabs(y); }
   3     };
   4 
   5     vector<double> V;
   6     ...
   7     sort(V.begin(), V.end(), less_mag());

计算一个vector的元素的合。在这个例子里面,函数对象是一个带有状态的自定义类的对象。

   1     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     vector<double> V;
   9     ...
  10     adder result = for_each(V.begin(), V.end(), adder()); [3]
  11     cout << "The sum is " << result.sum << endl;

删除一个list里面所有大于100小于1000的元素。

   1     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());

4. 概念

5. 类型

6. 函数

7. 备注

[1] The reason for the name "adaptable function object" is that adaptable function objects may be used by function object adaptors.

[2] The unary_function and binary_function bases are similar to the input_iterator, output_iterator, forward_iterator, bidirectional_iterator, and random_access_iterator bases: they are completely empty, and serve only to provide type information.

[3] 这只是展示如何使用函数对象的例子,并不建议这样计算vector元素的和。求和更好的方法是使用accumulate算法。

ch3n2k.com | Copyright (c) 2004-2020 czk.