> 文章列表 > 仿函数详解

仿函数详解

仿函数详解

目录

1、函数对象

2、谓词

2.1、一元谓词(谓词有一个参数

2.1.1、普通函数提供策略

2.1.2、仿函数(上面的函数调用)提供策略

2.1.3、一元谓词全部代码

 2.1、二元谓词(谓词有两个参数)

​编辑

3、内建函数对象


1、函数对象

重载了函数调用运算符()的类 实例化的对象 就叫做函数对象

函数对象+ ()触发 重载函数调用运算符 执行 ==》类似函数调用 (仿函数)

#include <iostream>using namespace std;
class Print
{
public:void operator()(char *str){cout<<str<<endl;}
};
void test01()
{Print ob;ob("hello world");Print()("hello wprld");
}int main(int argc, char *argv[])
{test01();return 0;
}


如果一个函数对象有一个参数叫做 一元函数对象

如果一个函数对象有两个参数叫做 二元函数对象

若果一个函数对象有三个参数叫做 多元函数对象

2、谓词

返回值类型 为 bool 类型的 普通函数或者 仿函数都叫做 谓词

如果谓词有一个参数 叫做一元谓词,但是一元谓词用于查找元素

如果参数有两个参数 叫做二元谓词,但是二元谓词用于容器中元素排序

2.1、一元谓词(谓词有一个参数)

用于查找容器中的元素

2.1.1、普通函数提供策略

bool greaterThan30(int value)
{return value>30;
}
//普通函数提供策略  函数名
ret = find_if(v1.begin(), v1.end(), greaterThan30);

greaterThan30函数参数为int类型,是因为底层中find_if函数的第三个参数是greaterThan30(参数为int类型)的入口地址,find_if将迭代器中的每一个元素都送到 greaterThan30(参数为int类型)函数进行比较,所以必然greaterThan30(参数为int类型)函数的参数为int 类型

2.1.2、仿函数(上面的函数调用)提供策略

class GreaterThan30
{
public:bool operator()(int value)     //find_if将迭代器中的每一个元素放入该成员函数中比较{return value>30;}
};
 //仿函数提供策略 类名称+()ret = find_if(v1.begin(), v1.end(), GreaterThan30());

2.1.3、一元谓词全部代码

//谓词的演示
#include<vector>
#include<algorithm>
bool greaterThan30(int value)
{return value>30;
}
class GreaterThan30
{
public:bool operator()(int value){return value>30;}
};void test02()
{vector<int> v1;v1.push_back(10);v1.push_back(30);v1.push_back(50);v1.push_back(70);v1.push_back(90);//find_if条件查找, 来自算法头文件 #include<algorithm>vector<int>::iterator ret;//普通函数提供策略  函数名//ret = find_if(v1.begin(), v1.end(), greaterThan30);//仿函数提供策略 类名称+()ret = find_if(v1.begin(), v1.end(), GreaterThan30());if(ret != v1.end()){cout<<"寻找的结果:"<<*ret<<endl;}
}
int main(int argc, char *argv[])
{test02();return 0;
}

 2.1、二元谓词(谓词有两个参数)

函数参数传递规律和一元谓词一样,用于容器中元素排序——算法排序

//二元谓词的演示
#include<vector>
#include<algorithm>void printVectorAll(vector<int> &v)
{vector<int>::iterator it;for(it=v.begin(); it!=v.end(); it++){cout<<*it<<" ";}cout<<endl;
}bool myGreaterInt(int v1, int v2)
{return v1>v2;
}
class MyGreaterInt1
{
public:bool operator()(int v1, int v2){return v1>v2;}
};
void test03()
{vector<int> v1;v1.push_back(10);v1.push_back(50);v1.push_back(30);v1.push_back(90);v1.push_back(70);cout<<"原始数据:";printVectorAll(v1);sort(v1.begin(), v1.end());  //默认排序方法是从小到大cout<<"\\n"<<"使用 sort 的默认排序规则:";printVectorAll(v1);sort(v1.begin(), v1.end(), myGreaterInt);cout<<"\\n"<<"使用全局普通函数,修改 sort 的默认排序规则:";printVectorAll(v1);sort(v1.begin(), v1.end(),MyGreaterInt1());cout<<"\\n"<<"使用仿函数,修改 sort 的默认排序规则:";printVectorAll(v1);sort(v1.begin(), v1.end(), greater<int>() );    //sort支持随机访问的容器,而 list 不是随机访问的容器,所以它是自己提供排序算法,而不使用 #include<algorithm>中的sor排序算法cout<<"\\n"<<" 使用算法库提供的方法,修改 sort 的默认排序规则:";printVectorAll(v1);
}int main(int argc, char *argv[])
{test03();return 0;
}

3、内建函数对象

1 6 个算数类函数对象 , 除了 negate 是一元运算,其他都是二元运算。
2 template < class T > T plus < T > // 加法仿函数
3 template < class T > T minus < T > // 减法仿函数
4 template < class T > T multiplies < T > // 乘法仿函数 5 template < class T > T divides < T > // 除法仿函数
6 template < class T > T modulus < T > // 取模仿函数
7 template < class T > T negate < T > // 取反仿函数
8 6 个关系运算类函数对象 , 每一种都是二元运算。
9 template < class T > bool equal_to < T > // 等于
10 template < class T > bool not_equal_to < T > // 不等于
11 template < class T > bool greater < T > // 大于
12 template < class T > bool greater_equal < T > // 大于等于
13 template < class T > bool less < T > // 小于
14 template < class T > bool less_equal < T > // 小于等于
15 逻辑运算类运算函数 , not 为一元运算,其余为二元运算。
16 template < class T > bool logical_and < T > // 逻辑与
17 template < class T > bool logical_or < T > // 逻辑或
18 template < class T > bool logical_not < T > // 逻辑非
//使用内建函数对象演示
#include<vector>
#include<algorithm>
void test03()
{vector<int> v1;v1.push_back(10);v1.push_back(50);v1.push_back(30);v1.push_back(90);v1.push_back(70);cout<<"原始数据:";printVectorAll(v1);sort(v1.begin(), v1.end(), greater<int>() );    //sort支持随机访问的容器,而 list 不是随机访问的容器,所以它是自己提供排序算法,而不使用 #include<algorithm>中的sor排序算法cout<<"\\n"<<"使用内建函数对象,修改 sort 的默认排序规则:";printVectorAll(v1);
}int main(int argc, char *argv[])
{test03();return 0;
}

 使用适配器将两个参数绑定为一个参数,使 find_if 函数不能出错,方便程序查询正确的结果,因为 find_if 本身是三个参数,你要传递四个参数,所以只能使用适配器

void test04()
{vector<int> v1;v1.push_back(10);v1.push_back(30);v1.push_back(50);v1.push_back(70);v1.push_back(90);//find_if条件查找vector<int>::iterator ret;ret = find_if(v1.begin(), v1.end(), bind2nd(greater<int>(), 30)  );   //使用适配器将两个参数绑定为一个参数,使 find_if 函数不能出错,方便程序查询正确的结果,因为 find_if 本身是三个参数,你要传递四个参数,所以只能使用适配器if(ret != v1.end()){cout<<"寻找的结果:"<<*ret<<endl;}
}int main(int argc, char *argv[])
{test04();return 0;
}