函数对象 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。
在函数对象和可适配的(adaptable)函数对象之间,有一个重要的但很细微的区别。[1] 一般来说,函数对象对于其参数的类型有限制。参数类型的限制可能并不简单,operator()可以重载,可以是成员模板函数,或者两者都是。相似的,程序没有办法确定参数的限制是什么。而adaptable函数对象指定参数和返回类型是什么,并提供了内嵌的类型定义,使这些类型有确定的名字并可以在程序中使用。如果类型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和binary_function来简化Adaptable Unary Function和Adaptable Binary Function的定义。[2]
Adaptable函数对象是很重要的,因为它们可以被函数对象适配器adaptor使用。函数对象适配器是一种能够转换或者操作其他函数对象的函数对象。STL提供了很多函数对象适配器,包括unary_negate(返回一个特定的AdaptablePredicate的逻辑非),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, and logical_not)。这样不用自己写新的函数对象,只要组合预定义好的的函数对象和函数对象适配器,就可以进行很复杂的运算了。
3. 例子
用随机数填充一个vector。在这个例子里面,函数对象就是一个函数指针。
按照绝对值给double型的vector排序,也就是说忽略元素的符号。在这个例子里面,函数对象是是一个自定义类的对象。
计算一个vector的元素的合。在这个例子里面,函数对象是一个带有状态的自定义类的对象。
删除一个list里面所有大于100小于1000的元素。
4. 概念
- Generator
- Unary Function
- Binary Function
- Predicate
- Binary Predicate
- Adaptable Generator
- Adaptable Unary Function
- Adaptable Binary Function
- Adaptable Predicate
- Adaptable Binary Predicate
5. 类型
- plus
- minus
- multiplies (formerly called times)
- divides
- modulus,
- negate
- equal_to
- not_equal_to
- greater
- less
- greater_equal
- less_equal,
- logical_and
- logical_or
- logical_not
- subtractive_rng
- identity
- project1st
- project2nd
- select1st
- select2nd
- unary_function
- binary_function
- unary_compose
- binary_compose
- unary_negate
- binary_negate
- binder1st
- binder2nd
- pointer_to_unary_function
- pointer_to_binary_function
6. 函数
- compose1
- compose2
- not1
- not2
- bind1st
- bind2nd
- ptr_fun
7. 备注
[1] 之所以称为"adaptable function object"可适配的函数对象,是因为它能够被函数对象适配器所使用。
[2] unary_function, binary_function和input_iterator, output_iterator, forward_iterator, bidirectional_iterator, random_access_iterator 是类似的: 它们是完全空的,只是提供了类型信息。
[3] 这只是展示如何使用函数对象的例子,并不建议这样计算vector元素的和。求和更好的方法是使用accumulate算法。