仿函数
一,概述
仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。 有些功能的的代码,会在不同的成员函数中用到,想复用这些代码。
1)公共的函数,可以,这是一个解决方法,不过函数用到的一些变量,就可能成为公共的全局变量,再说为了复用这么一片代码,就要单立出一个函数,也不是很好维护。 2)仿函数,写一个简单类,除了那些维护一个类的成员函数外,就只是实现一个operator(),在类实例化时,就将要用的,非参数的元素传入类中。
二,仿函数(functor)在各编程语言中的应用
1)C语言使用函数指针和回调函数来实现仿函数,例如一个用来排序的函数可以这样使用仿函数
#include <stdio.h> #include <stdlib.h> //int sort_function( const void *a, const void *b); int sort_function( const void *a, const void *b) { return *(int*)a-*(int*)b; } int main() { int list[5] = { 54, 21, 11, 67, 22 }; qsort((void *)list, 5, sizeof(list[0]), sort_function);//起始地址,个数,元素大小,回调函数 int x; for (x = 0; x < 5; x++) printf("%i\n", list[x]); return 0; }
2)在C++里,我们通过在一个类中重载括号运算符的方法使用一个函数对象而不是一个普通函数。
#include <iostream> #include <algorithm> using namespace std; template<typename T> class display { public: void operator()(const T &x) { cout<<x<<" "; } }; int main() { int ia[]={1,2,3,4,5}; for_each(ia,ia+5,display<int>()); return 0; }
三,仿函数在STL中的定义
要使用STL内建的仿函数,必须包含头文件。而头文件中包含的仿函数分类包括
1)算术类仿函数
加:plus<T>
减:minus<T>
乘:multiplies<T>
除:divides<T>
模取:modulus<T>
否定:negate<T>
例子:
#include <iostream> #include <numeric> #include <vector> #include <functional> using namespace std; int main() { int ia[]={1,2,3,4,5}; vector<int> iv(ia,ia+5); cout<<accumulate(iv.begin(),iv.end(),1,multiplies<int>())<<endl; cout<<multiplies<int>()(3,5)<<endl; modulus<int> modulusObj; cout<<modulusObj(3,5)<<endl; // 3 return 0; }
2)关系运算类仿函数
等于:equal_to<T>
不等于:not_equal_to<T>
大于:greater<T>
大于等于:greater_equal<T>
小于:less<T>
小于等于:less_equal<T>
从大到小排序:
#include <iostream> #include <algorithm> #include <vector> using namespace std; template <class T> class display { public: void operator()(const T &x) { cout<<x<<" "; } }; int main() { int ia[]={1,5,4,3,2}; vector<int> iv(ia,ia+5); sort(iv.begin(),iv.end(),greater<int>()); for_each(iv.begin(),iv.end(),display<int>()); return 0; }