所谓仿函数,是定义了operator()的对象,下面这个例子:
FunctionObject fo;
fo();
其中表达式fo()是调用仿函数fo的operator()。而非调用函数fo().
你可以将仿函数看做一般函数,只不过用的是一种更复杂的撰写手段:并非将所有语句放在函数体中:
void fo() { statements; }
而是在仿函数类别的operator()体内撰写程序代码。
class FunctionObject { public: void operator() { statements; } };
而函数指针就先对来说比较简单,
void (*ptrA)(void); void funcA(void); ptrA = funcA;//为函数指针赋值 void (*ptrA)(void);//这就相当于调用funcA
我主要说一下这俩者在写模板的时候的区别,先看代码吧:
#include<iostream> #include<string> #include<algorithm> using namespace std; template <typename InputIterator, typename T > inline T accumulate(InputIterator first, InputIterator last, T init, T (*ptrA)(T, T)) {//函数指针 while (first != last) { init = (*ptrA)(init, *first); ++first; } return init; } int funcA(int x, int y) { return x + y; } int main(void) { int a[5] = {2, 5, 7, 9, 11}; random_shuffle(&a[0], &a[5]); int x = ::accumulate(&a[0], &a[5], 0, funcA); cout << x << endl; return 0; }
这里就是计算a数组里面全部的和,放在x变量里面。
首先,这个函数的原型是T (*ptrA)(T x, T y);如果我想提升我处理数据的速度,让时间少浪费由于函数值传递引起的拷贝上,于是我需要这样写函数 T funcA(const int& x, const int& y)。这样写的话,我们原来的函数T (*ptrA)(T x, T y)就不能匹配这个函数,于是我们就要重载函数。还有就是效率问题,函数指针的调用,我们的电脑需要做很多工作,比如说保存当前的寄存器值,传递参数,返回值,返回到函数调用地方继续执行等。
幸运的是,这一切问题都可以通过仿函数来解决,如下:
#include<iostream> #include<string> #include<algorithm> using namespace std; template <typename InputIterator, typename T, typename FunObject> inline T accumulate(InputIterator first, InputIterator last, T init, FunObject object) {//函数对象 while (first != last) { init = object(init, *first); ++first; } return init; } template < typename T> class Test { public: T operator()(const T& x, const T& y) { return x + y; } }; int main(void) { int a[5] = {2, 5, 7, 9, 11}; random_shuffle(&a[0], &a[5]); int x = ::accumulate(&a[0], &a[5], 0, Test<int>()); cout << x << endl; return 0; }
这样就解决了效率和函数重载的问题了。
转自:http://www.cnblogs.com/lutianba/archive/2013/05/18/3086287.html