1. 概念
模仿函数的类,使用方式如同函数。本质是类中重载括弧运算符operator()
。
2. 场景
不同函数复用相同处理代码。
3. 使用
3.1 C语言的处理方式
使用函数指针和回调函数来实现代码复用。例如qsort()
#include <stdio.h>
#include <stdlib.h> int arr_sort( const void *a, const void *b) { return *(int*)a-*(int*)b; } int main() { int arr[5] = { 4, 1, 2, 5, 6 }; qsort(arr, 5, sizeof(arr[0]), arr_sort); int i; for (i = 0; i < 5; i++){ printf("%i\n", arr[i]); } return 0; }
3.2 C++语言的处理方式
- 函数指针方式
#include <iostream>
#include <algorithm> using namespace std; inline bool Sort(int a,int b){ return a > b; } inline void Display(int a){ cout << a << endl; } int main() { int arr[5] = { 4, 1, 2, 5, 6 }; sort(arr, arr+5,Sort); for_each(arr,arr+5,Display); return 0; }
- 函数模板方式
#include <iostream>
#include <algorithm> using namespace std; template<class T> inline bool Sort(T const& a,T const& b){ return a > b; } template<class T> inline void Display(T a){ cout << a << endl; } int main() { int arr[5] = { 4, 1, 2, 5, 6 }; sort(arr, arr+5,Sort<int>); for_each(arr,arr+5,Display<int>); return 0; }
- 仿函数方式
class Sort{
public: bool operator()(int a,int b) const { return a > b; } }; class Display{ public: void operator()(int a) const{ cout << a << endl; } }; int main() { int arr[5] = { 4, 1, 2, 5, 6 }; sort(arr, arr+5,Sort()); for_each(arr,arr+5,Display()); return 0; }
4.仿函数模板方式
template<class T> class Sort{ public: inline bool operator()(T const& a,T const& b) const { return a > b; } }; template<class T> class Display{ public: inline void operator()(T const& a) const{ cout << a << endl; } }; int main() { int arr[5] = { 4, 1, 2, 5, 6 }; sort(arr, arr+5,Sort<int>()); for_each(arr,arr+5,Display<int>()); return 0; }
STL的仿函数
在<functional>
头文件中定义了如下三类仿函数:
- 算术类仿函数
操作 | 仿函数 |
---|---|
加 | plus<T> |
减 | minus<T> |
乘 | multiplies<T> |
除 | divides<T> |
取模 | modulus<T> |
取反 | negate<T> |
template< class T>
struct plus:binary_function<T,T,T>{
public:
T operator()(T const& l,T const&r){
return l+r; } };
例如:
#include <iostream>
#include <numeric> // accumulate #include <functional> // using namespace std; int main(){ int arr[]={1,2,3,4,5}; vector<int> iv(ia,ia+5); cout<< accumulate(iv.begin(),iv.end(),1,multiplies<int>()) <<endl; return 0; }
Boost lambda表达式
cout<< accumulate(iv.begin(),iv.end(),1,_1*_2) <<endl;
或者
#include <iostream>
#include <algorithm> // for_each() transform() #include <functional> using namespace std; inline void Print(int a){ cout << a << endl; } int main(){ int first[]={1,2,3,4,5}; int second[]={10,20,30,40,50}; int results[5]; transform (first, first+5, second, results, std::plus<int>()); for_each(results,results+5,Print); return 0; }
Boost lambda表达式
transform (first, first+5, second, results, _1+_2);
- 关系运算类仿函数
操作 | 仿函数 |
---|---|
等于 | equal_to<T> |
不等于 | not_equal_to<T> |
大于 | greater<T> |
大于等于 | greater_equal<T> |
小于 | less<T> |
小于等于 | less_equal<T> |
template< class T> struct equal_to:binary_function<T,T,bool>{ public: bool operator()(T const& l,T const&r){ return l == r; } };
例如:
#include <iostream>
#include <algorithm> // for_each() sort() #include <functional> using namespace std; inline void Print(int a){ cout << a << endl; } int main(){ int arr[]={1,2,3,4,5}; sort(arr,arr+5,greater<int>()); for_each(arr,arr+5,Print); return 0; }
Boost lambda表达式
sort(arr,arr+5,_1>_2);
- 逻辑运算仿函数
操作 | 仿函数 |
---|---|
逻辑与 | logical_and<T> |
逻辑或 | logical_or<T> |
逻辑否 | logical_not<T> |
例如:
布尔数组整体取反
#include <iostream> // cout, boolalpha
#include <functional> // std::logical_not #include <algorithm> // std::transform using namespace std; inline void Print(bool a){ cout << a << endl; } int main () { bool values[] = {true,false,true,false}; transform (values, values+4, values, logical_not<bool>()); cout.flags(ios::boolalpha); for_each(values, values+4,Print); return 0; }
Boost lambda表达式
transform (values, values+4, values, !_1);
两个布尔数组对应元素相与
#include <iostream> // cout, boolalpha
#include <functional> // std::logical_not #include <algorithm> // std::transform using namespace std; inline void Print(bool a){ cout << a << endl; } int main () { bool values1[] = {true,false,true,false}; bool values2[] = {false,true,false,true}; bool result[4]; transform(values1, values1+4,values2, result, logical_and<bool>()); cout.flags(ios::boolalpha); for_each(result,result+4,Print); return 0; }
Boost lambda表达式
transform(values1, values1+4,values2, result, _1 and _2);