## page was renamed from 函数对象概述 = 函数对象 Function Objects = == 概述 == 函数对象(Function Object),或者叫做仿函数Functor(这两个是同义词)是任何能够像函数一样被调用的对象。一个普通函数是一个函数对象,一个函数指针也是函数对象;更一般的讲,定义了()运算符的类的对象也是函数对象。 == 描述 == 基本的函数对象的概念有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)。这样不用自己写新的函数对象,只要组合预定义好的的函数对象和函数对象适配器,就可以进行很复杂的运算了。 == 例子 == 用随机数填充一个vector。在这个例子里面,函数对象就是一个函数指针。 {{{#!cplusplus vector V(100); generate(V.begin(), V.end(), rand); }}} 按照绝对值给double型的vector排序,也就是说忽略元素的符号。在这个例子里面,函数对象是是一个自定义类的对象。 {{{#!cplusplus struct less_mag : public binary_function { bool operator()(double x, double y) { return fabs(x) < fabs(y); } }; vector V; ... sort(V.begin(), V.end(), less_mag()); }}} 计算一个vector的元素的合。在这个例子里面,函数对象是一个带有状态的自定义类的对象。 {{{#!cplusplus struct adder : public unary_function { adder() : sum(0) {} double sum; void operator()(double x) { sum += x; } }; vector V; ... adder result = for_each(V.begin(), V.end(), adder()); [3] cout << "The sum is " << result.sum << endl; }}} 删除一个list里面所有大于100小于1000的元素。 {{{#!cplusplus list L; ... list::iterator new_end = remove_if(L.begin(), L.end(), compose2(logical_and(), bind2nd(greater(), 100), bind2nd(less(), 1000))); L.erase(new_end, L.end()); }}} == 概念 == * Generator * Unary Function * Binary Function * Predicate * Binary Predicate * Adaptable Generator * Adaptable Unary Function * Adaptable Binary Function * Adaptable Predicate * Adaptable Binary Predicate == 类型 == * 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 == 函数 == * compose1 * compose2 * not1 * not2 * bind1st * bind2nd * ptr_fun == 备注 == [1] 之所以称为"adaptable function object"可适配的函数对象,是因为它能够被函数对象适配器所使用。 [2] unary_function, binary_function和input_iterator, output_iterator, forward_iterator, bidirectional_iterator, random_access_iterator 是类似的: 它们是完全空的,只是提供了类型信息。 [3] 这只是展示如何使用函数对象的例子,并不建议这样计算vector元素的和。求和更好的方法是使用accumulate算法。