A 函数对象
概念:
重载函数调用运算符的类实例化的对象,就叫函数对象.又名仿函数,函数对象和()触发重载函数调用运算符的执行。
作用:
为算法提供策略
示例:
#include <iostream>
using namespace std;
class MyClass
{
public:
void operator()(int x, int y) {}
};
int main(int argc, char const *argv[])
{
//函数对象(仿函数)
MyClass c;
return 0;
}
B 谓词
概念:
只要 返回值为bool类型的普通函数 或 仿函数 都叫谓词
- 有一个参数 叫一元谓词
- 有两个参数 叫二元谓词。
#include <iostream>
using namespace std;
//谓词
bool method01() {}
// 谓词
class MyClass
{
bool operator()() { }
};
//是谓词 更是一元谓词
bool method02(int x) {}
// 二元谓词
bool method03(int x, int y) {}
int main(int argc, char const *argv[])
{
return 0;
}
C 内建函数对象
概念 : c++提供的函数对象
1 算法类函数对象
template<classT> T plus<T>//加法仿函数
template<classT> T minus<T>//减法仿函数
template<classT> T multiplies<T>//乘法仿函数
template<classT> T divides<T>//除法仿函数
template<classT> T modulus<T>//取模(取余)仿函数
template<classT> T negate<T>//取反仿函数
注意:6个算数类函数对象,除了negate是一元运算,其他都是二元运算
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
// template<classT> T plus<T>//加法仿函数
cout << "加法仿函数" << endl;
plus<int> p1;
int x = p1(21, 4);
cout << "x = " << x << endl;
// template<classT> T negate<T>//取反仿函数
cout << "取反函数不能对bool取反" << endl;
negate<int> n1;
int z = n1(99);
cout << "z = " << z << endl;
return 0;
}
2 关系运算类函数对象
语法:
template<class T> bool equal_to<T>//等于
template<class T> bool not_equal_to<T>//不等于
template<class T> bool greater<T>//大于
template<class T> bool greater_equal<T>//大于等于
template<class T> bool less<T>//小于
template<class T> bool less_equal<T>//小于等于
注意:6个关系运算类函数对象,每一种都是二元谓词
逻辑运算类运算函数
template<class T>bool1ogical_and<T>//逻辑与
template<class T>bool1ogical_or<T>//逻辑或
template<class T>bool1ogical_not<T>//逻辑非
注意:3个逻辑运算类运算函数,not为一元谓词,其余为二元谓词。
D 适配器
1 函数对象适配器
用的函数名: for_each ( )
特点:
- 将函数对象作为适配器
使用:
- bind2nd 将绑定的数据放置第二个参数位置
- bind1st 将绑定的数据放置第一个参数位置
步骤:
- 1,创建一个类
- 2,使该类继承与binary_function
- 3,泛型萃取
- 第一泛型为重载的() 运算符中第一个形参的数据类型
- 第二泛型为重载的() 运算符中第二个形参的数据类型
- 第三泛型为重载的()运算符中返回值的数据类型
- 4,在该类中重载() 运算符 记得尾部加 const
- 5,创建该类对象
- 6,使用算法,在算法适配器中使用bind1st或bind2nd绑定该类对象与传入的值
示例:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 1,创建一个类
// 2,使该类继承与binary_function
// 3,泛型萃取
class MyClass : public binary_function<int, int, void>
{
public:
在该类中重载() 运算符 记得尾部加 const
void operator()(int x, int y) const
{
cout << "x = " << x << endl;
cout << "y = " << y << endl;
}
};
int main(int argc, char const *argv[])
{
vector<int> ns;
ns.push_back(1);
ns.push_back(2);
ns.push_back(3);
ns.push_back(4);
// 第一种遍历方式 auto 自适应去找我的类型 原生的复杂
// for (auto it = ns.begin(); it != ns.end(); it++)
// {
// cout << *it << endl;
// }
// 5,创建该类对象
MyClass c;
//使用算法,在算法适配器中使用bind1st或bind2nd绑定该类对象与传入的值 必须继承algorithm
for_each(ns.begin(), ns.end(), bind1st(c, 10));
return 0;
}
2 函数指针适配器
特点:
以全局函数 作为适配器 prt_fun(函数名)
使用:
- bind2nd 将绑定的数据放置第二个参数位置
- bind1st 将绑定的数据放置第一个参数位置
- ptr_fun(函数名)
步骤:
- 1,定义一个全局函数,该函数两个参数
- 2,使用算法,在算法适配器中使用bind1st或bind2nd绑定该函数与传入的值
示例:
#include <iostream>
#include <set>
#include <algorithm> //for_each 头文件
using namespace std;
void my_test(int x, int y)
{
cout << "x = " << x << endl;
cout << "y = " << y << endl;
}
int main(int argc, char const *argv[])
{
set<int> ns;
ns.insert(1);
ns.insert(2);
ns.insert(3);
ns.insert(4);
//遍历
for_each(ns.begin(), ns.end(), bind2nd(ptr_fun(my_test),99));
return 0;
}
3 成员函数适配器
特点:
将成员函数(地址)作为适配器
使用:
- bind2nd 将绑定的数据放置第二个参数位置
- bind1st 将绑定的数据放置第一个参数位置
- mem_fun_ref(&类名 :: 函数名)
注意
mem_fun_ref(&类名::函数名) 包裹的参数只能有一个 所以也就没有绑定
步骤:
- 1,创建一个类
- 2,在该类中编写成员函数
- 3,使用算法,在算法适配器中使用mem_fun_ref包括该函做
注意:
- 集合中存储的对象所在的类与成员函数所在的类为同一个类
- 该函数必须是无参的
- 集合中的获取的数据
示例:
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
class MyClass
{
public:
int x;
MyClass(int x) : x(x) {}
void my_show()
{
cout << "x = " << this->x << endl;
}
};
int main(int argc, char const *argv[])
{
list<MyClass> ls;
ls.push_back(MyClass(1));
ls.push_back(MyClass(2));
ls.push_back(MyClass(3));
ls.push_back(MyClass(4));
// 遍历
for_each(ls.begin(), ls.end(),mem_fun_ref(&MyClass::my_show));
return 0;
}
4 取反适配器
- notl 一元函数对象取反
- not2 二元函数对象取反
示例:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void show(int x)
{
cout << x << ",";
}
bool dy5(int x, int y)
{
return x > y;
}
class MyClass : public binary_function<int, int, bool>
{
public:
bool operator()(int x, int y) const
{
return x > y;
}
};
int main(int argc, char const *argv[])
{
vector<int> nums;
nums.push_back(2);
nums.push_back(1);
nums.push_back(3);
nums.push_back(6);
nums.push_back(9);
for_each(nums.begin(), nums.end(), ptr_fun(show));
cout << endl;
// 查找vector中第一个大于5的值
// vector<int>::iterator it =
find_if(nums.begin(), nums.end(), bind2nd(ptr_fun(dy5), 5));
// auto it =
find_if(nums.begin(), nums.end(), bind2nd(MyClass(), 5));
auto it = find_if(nums.begin(), nums.end(), not1(bind2nd(MyClass(), 5)));
cout << *it << endl;
// 排序算法
sort(nums.begin(), nums.end(), not2(less<int>()));
for_each(nums.begin(), nums.end(), ptr_fun(show));
cout << endl;
return 0;
}