![](https://i-blog.csdnimg.cn/blog_migrate/ca427f6b79c07dff284d6823c31fc6cd.png)
仿函数(functor)作为STL六大组件(components)中的一个,也称函数对象(function object),其实就是重载了operator()
操作符的 struct / class
。
1. 如何将操作作为算法的参数 & STL的选择
若是想将某种操作当作算法的参数,有如下唯二两种方式:
- 将操作(可能含有数条以上的指令)设计为一个函数,再将函数指针作为算法的函数指针参数(例子见c++中的函数指针转函数参数);
- 将操作设计为一个仿函数(语言层面为自定义数据类型,class/struct),再以仿函数实例化一对象(通常时临时/匿名对象),并以此对象作为算法的参数(例子参见sort函数及其元素排序方式定制);
就以上两种方式,其中函数指针不能够满足 STL 对抽象的要求,不能够与 STL 组件搭配,也不能够满足软件积木的要求。所以在 STL 实现当中,使用仿函数作为算法的操作参数。所以 STL 算法中,对于缺省运算的算法中,所缺省的运算参数除了默认参数外,还可以传入仿函数,以便采取其它的运算策略(如sort函数,默认采用从小到大的排序方式,但是可以使用greater仿函数,改为从大到小排序)。如下代码所示:
//using default comparision(operator <)
sort(myvec.begin(), myvec.end());
//using function as comp
sort(myvec.begin(), myvec.end(), myfunc);
//using object as comp
sort(myvec.begin(), myvec.end(), myobj);
//using explicitly default comparision(operator <)
sort(myvec.begin(), myvec.end(), less<int>());
//using another comparision criteria(operator >)
sort(myvec.begin(), myvec.end(), greater<int>());
//以下两个没有融入STL,因为没有继承binary_function
struct myclass {
bool operator(int i, int j) { return i < j; }
} myobj;
bool myfunc(int i, int j) { return i < j; }
//相对关系类(relational)
template<class T>
struct greater<T> : public binary_function<T, T, bool> {
bool operator(const T& x, const T& y) const {
return x > y;
}
};
template<class T>
struct less<T> : public binary_function<T, T, bool> {
bool operator(const T& x, const T& y) const {
return x < y;
}
};
注意:任何使用 STL 内建仿函数的意图,都必须含入 <function>
头文件, SGI 则将它们实际定义于 <stl_function.h>
文件中。
2. 仿函数能够进行配接的条件
为了能够被配接器(adaptor)修饰,每一个仿函数必须定义自己的相应类型(associate types),就像迭代器如果想要兼容 STL 要定义出5个相应类型一样(见STL迭代器详解:3. std::iterator的保证)。这些相应类型是为了让配接器能够取出仿函数的信息。配接器之于仿函数,就类似于 iterator_traits 之于迭代器的关系(见STL迭代器详解: 2. 迭代器相关类型的取用——iterator_traits机制),也是运用了 STL 中广泛运用的 traits 技巧。
仿函数的相应类型主要用来表现函数参数类型和传回值类型。在 <stl_function.h> 文件中定义了 unary_function 和 binary_function 两个 classes,分别代表一元仿函数和二元仿函数(不支持三元仿函数),其定义中只包含typedef的相应类型,继承之后对自定义仿函数不会带来多余的空间开销。
3. 仿函数的分类
仿函数按照操作数(operand)个数可分为:一元(unary),二元(binary);
仿函数按照功能(function)可分为:算术类(Arithmetic),逻辑运算类(Logical)、相对关系类(Relational);
类别 | 二元运算(binary function) | 一元运算(unary function) |
---|---|---|
算术类(Arithmetic) | plus<T>; minus<T>; multiplies<T>; divides<T>; modulus<T>; | negate<T>; |
逻辑运算类(Logical) | logical_and<T>; logical_or<T>; | logical_not<T>; |
相对关系类(Relational) | equal_to<T>; not_equal_to<T>; greater<T>; greater_equal<T>; less<T>; less_equal<T>; | / |
此外,还有证同(identity,返回自身,unary)、选择(selection,接受一个pair,返回pair中的first或second,binary)、投影(project,接收两个参数,忽略其中一个,只传回另一个,binary)。