一. 概念:
函数对象function objects,又名仿函数,是一个定义了operator()操作的对象。
class FunctionObjectType { public: void operator() { statements } };
二. 仿函数当做排序准则:
程序员经常需要将某些class object以已序的形式放到容器中,然而有时你无法使用一般的operator<来对这些对象排序,这时可以仿函数。
#include <iostream> #include <string> #include <set> #include <algorithm> using namespace std; class Person { public: string firstname() const; string lastname() const; ... }; /* 仿函数,按名字排序 * - operator() returns whether a person is less than another person */ class PersonSortCriterion { public: bool operator() (const Person& p1, const Person& p2) const { /* a person is less than another person * - if the last name is less * - if the last name is equal and the first name is less */ return p1.lastname()<p2.1astname() || (! (p2.1astname()<p1.lastname()) && p1.firstname()<p2.firstname()); } }; int main() { //声名 set ,用这个仿函数 typedef set<Person,PersonSortCriterion> PersonSet; //create such a collection PersonSet coll; ... //do something with the elements PersonSet::iterator pos; for (pos = coll.begin(); pos != coll.end();++pos) { ... } ... }
三. 拥有内部状态的仿函数:
#include <iostream>
#include <list>
#include <algorithm>
#include "print.hpp"
using namespace std;
class IntSequence {
private:
int value;
public:
//constructor
IntSequence (int initialValue)
: value(initialValue) {
}
//''function call''
int operator() () {
return value++;
}
};
int main()
{
list<int> coll;
//insert values from 1 to 9
generate_n (back_inserter(coll), //start
9, //number of elements
IntSequence (1)); //generates values
PRINT_ELEMENTS(coll); //1 2 3 4 5 6 7 8 9
//replace second to last element but one with values starting at 42
generate (++coll.begin(), //start
--coll.end(), //end
IntSequence (42)); //generates values
PRINT_ELEMENTS(coll); //1 42 43 44 45 46 47 48 9
}
注:generate/generate_n 通过一个数值产生器类生成的数值来初始化一个容器, 通过将产生器函数gen返回的值赋给由迭代器指定的[first, last) or [first, first + n)范围内的所有元素, generate和generate_n算法初始化或重新初始化了一个序列。
以引用方式传递仿函数:
generate_n<back_insert_iterator<list<int> >, int, IntSequence&> (back_inserter(coll), //start 4, //number of elements seq); //generates values调用后,seq的值已经改变,下次再调用会用上次的值。
三. for_each()的返回值
for_each()可以返回其仿函数,这样你可以返回值获取仿函数的状态了。
MeanValue mv = for_each (coll.begin(), coll.end(), //range MeanValue()); //operation cout << "mean value: " << mv.value() << endl;
四. 预定义的仿函数
#include <functional>
negate<type>() | - param |
plus<type>() | param1 + param2 |
minus<type>() | param 1 - param2 |
multiplies<type>() | param1 * param2 |
divides<type>() | param1 / param2 |
modulus <type>() | param1 % param2 |
equal_to<type>() | param1 == param2 |
not_equal_to<type>() | param1 ! = param2 |
less<type>() | param1 < param2 |
greater<type>() | param1 > param2 |
less_equal<type>() | param1 <= param2 |
greater_equal<type>() | param1 >= param2 |
logical_not<type>() | ! param |
logical_and<type>() | param1 && param2 |
logical_or<type> () | param1 | | param2 |
typedef set<int, greater<int> > IntSet; typedef set<int, less<int> > IntSet;