c++ STL (四 仿函数)

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++语言的处理方式

  1. 函数指针方式
#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;   
}
  1. 函数模板方式
#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;   
}
  1. 仿函数方式
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>头文件中定义了如下三类仿函数:

  1. 算术类仿函数
操作仿函数
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);
  1. 关系运算类仿函数
操作仿函数
等于 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);
  1. 逻辑运算仿函数
操作仿函数
逻辑与 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);




posted @ 2020-02-22 10:04  卖雨伞的小男孩  阅读(696)  评论(0编辑  收藏  举报