仿函数(Functors,Function Objects)
仿函数,又叫函数对象。我们都清楚普通函数的定义与使用方法,我们可以说任何东西,只要其行为像函数,它就是个函数。如果我们定义了一个对象,其行为像函数,它就可以被当函数来使用。所谓函数行为,是指可以“使用小括号传递参数,蔚以调用某个东西”。例如:
function(arg1, arg2);//a function call
函数对象概念包括Generator, Unary Function(一元函数), 和Binary Function(二元函数),分别可以f(),f(x),f(x, y)的形式调用。返回bool类型的仿函数比较特殊,比如返回bool的Unary Function叫做Predicate(谓词),返回bool的Binary Function叫做Binary Predicate。
那么在c++中仿函数可以这么理解:
使一个类的使用看上去像一个函数,同时它是通过通过重载类的()操作符来实现的。
例如:
class CPrintInt { public: void operator()(int nElements)const//使用重载()来实现 { cout <<"call operator():"<< nElements << endl; } }; CPrintInt CPrint; CPrint(10);//像函数一样去使用 CPrint.operator()(10);//显示调用
#include "stdafx.h" #include <string.h> #include <algorithm> #include <vector> #include <deque> #include <functional> #include <iostream> #include <list> #include <sstream> #include <iterator> #include <functional> #include <stdlib.h> using namespace std; /************************************************************************/ /* 比较两个参数大小,确定排序规则 */ /* 返回值: */ /* > 0 a排在b后面 */ /* = 0 排序不确定 */ /* < 0 a排在b前面 */ /************************************************************************/ int CompareAge(const void *a, const void *b) { return *((int*)(a)) - *((int*)(b)); } //define less function object class CUseLess { public: bool operator()(int a, int b)const { return a < b; } }; int _tmain(int argc, _TCHAR* argv[]) { const int MaxNum = 5; int nAge[MaxNum] = {10, 12, 30, 4, 27}; //C语言使用函数指针和回调函数来实现仿函数 printf("Use function point and Callback function\n"); qsort(nAge, sizeof(nAge)/sizeof(0), sizeof(int), CompareAge); for (int i = 0; i < MaxNum; i++) { printf("%d ",nAge[i]); } printf("\n"); //C++中,使用在一个类中重载括号运算符的方法,使一个类对应具有函数行为 vector <int> vecCollector; for (int i = 0; i < MaxNum; ++i) { vecCollector.push_back(nAge[i]); } //其实sort排序算法中,我们经常会引用“functional”中预定义的仿函数, //诸如less,greater,greater_equal等,这里只是使用用户定义版的less,实现原理是一样的。 //sort(vecCollector.begin(), vecCollector.end(), less<int>());//functional中的仿函数 cout << "Use Fucntion object" << endl; sort(vecCollector.begin(), vecCollector.end(), CUseLess()); //用户自定义的仿函数 copy(vecCollector.begin(), vecCollector.end(), ostream_iterator<int>(cout," ")); cout << endl; return 0; }
输出:
STL中提供了许多预定义的仿函数,要使用这些预定义的仿函数必须包含头文件<functional>,,对于对对象排序或进行比较时,一般都是以less<>为预设准则。表1列出了这些仿函数。