导航
要使用头文件#include < functional>
1.认识bind2nd 与 bind1st 的区别
2.取反适配器 not1()
3.函数指针适配器 ptr_fun
4.成员函数适配器 mem_fun_ref()或者mem_fun对类内函数进行适配,
————————————————————————————————————————
1.认识bind2nd 与 bind1st 的区别
先写一个容器遍历:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>
//函数对象适配器
class Print
{
public:
void operator()(int val)
{
cout<<val<<endl;
}
};
void test()
{
vector<int> v;
for(int i=0;i<10;i++){
v.push_back(i);
}
for_each(v.begin(),v.end(),Print());
}
int main()
{
test();
return 0;
}
若我们想将中间遍历的数都加上一个数呢:我们就要用到适配器
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>
//函数对象适配器
class Print:public binary_function<int,int,void> //加入三个参数:仿函数括号正两个变量类型和返回值类型
{
public:
void operator()(int val,int start) const //这里添加一个值为我们要加入的
{
cout<<val+start<<endl;
}
};
void test()
{
vector<int> v;
for(int i=0;i<10;i++){
v.push_back(i);
}
int num;
cin>>num; //这里可以自己手动写入要输入的值
//***************************************************************************
for_each(v.begin(),v.end(),bind2nd(Print(),num)); //将要添加的数包含在bind2sd中
//***************************************************************************
//3个步骤
//1.将参数进行指定bind2nd
//2.做继承public binary_function(三个参数)
//3.在仿函数后面加const
}
int main()
{
test();
return 0;
}
运行结果:
我们再看下bind2nd 与bind1st的区别:
相同点:两个使用之后结果相同
不同点:两者的绑定参数不一样
对于bind2nd打印下各个参数结果:
对于bind1st打印下各个参数结果:
结论:可以看到各自在仿函数中的参数绑定的各个值都不相同,结果还是一样的
————————————————————————————————————————
2.取反适配器
我们先写一个find_if()函数:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>
class Greater
{
public:
bool operator()(int val)
{
return val>5; //大于五
}
};
void test()
{
vector<int> v;
for(int i=0;i<10;i++){
v.push_back(i);
}
vector<int>::iterator it = find_if(v.begin(),v.end(),Greater()); //返回迭代器
if(it != v.end())
{
cout<<"找到,对应值为"<<*it<<endl;
}
else
{
cout<<"未找到"<<endl;
}
}
int main()
{
test();
return 0;
}
运行结果为:找到,对应值为5
若我们找不小于5的数呢,可以加上not1(),
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>
class Greater:public unary_function<int,bool> //加上括号中参数和返回值参数
{
public:
bool operator()(int val) const
{
return val>5; //大于五
}
};
void test()
{
vector<int> v;
for(int i=0;i<10;i++){
v.push_back(i);
}
//***************************************************************************
vector<int>::iterator it = find_if(v.begin(),v.end(),not1(Greater())); //返回迭代器
//***************************************************************************
if(it != v.end())
{
cout<<"找到,对应值为"<<*it<<endl;
}
else
{
cout<<"未找到"<<endl;
}
}
//三个步骤
//1. 添加not1()
//2.继承 :public unary_function<int,bool>
//3.在仿函数后面加上const
int main()
{
test();
return 0;
}
缺点是:不好手动添加更改的值,所以只能在仿函数中更改
————————————————————————————————————————
如何让其手动加入大于的值呢:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>
void test()
{
vector<int> v;
for(int i=0;i<10;i++){
v.push_back(i);
}
int num;
cin>>num;
//这里使用到了greater<int>()为内建函数大于,可用于sort排序,
//这里旁边再加上手动的num,外面再包上bind2nd,这样就可以手动输入,并且执行
//***************************************************************************
vector<int>::iterator it = find_if(v.begin(),v.end(),bind2nd(greater<int>(),num)); //返回迭代器
//***************************************************************************
if(it != v.end())
{
cout<<"找到,对应值为"<<*it<<endl;
}
else
{
cout<<"未找到"<<endl;
}
}
int main()
{
test();
return 0;
}
运行结果:
要是我们使用到取反呢,直接在bind2nd()外面加上一个not1()就可以了
就像这样:
not1(bind2nd(greater(),num))
————————————————————————————————————————
3.函数指针适配器 ptr_fun()
这里我们还是遍历容器,只不过这里我们自己新建的是函数,也还是可以手动输入
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>
void Print(int val,int start)
{
cout<<val+start<<endl;
}
void test()
{
vector<int> v;
for(int i=0;i<10;i++){
v.push_back(i);
}
int num;
cin>>num; //这里可以自己手动写入要输入的值
//函数指针适配器 将函数指针 适配称 函数对象
//ptr_fun()
//***************************************************************************
for_each(v.begin(),v.end(),bind2nd(ptr_fun(Print),num)); //将要添加的数包含在bind2sd中
//***************************************************************************
}
int main()
{
test();
return 0;
}
运行结果:
————————————————————————————————————————
4.成员函数适配器 mem_fun_ref()对类内函数进行适配
在类中创建输出函数:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>
//创建类
class Person
{
public:
Person(string name,int age)
{
this->m_name = name;
this->m_age = age;
}
void showPer()
{
cout<<"姓名:"<<m_name<<" 年龄:"<<m_age<<endl;
}
string m_name;
int m_age;
};
void test()
{
vector<Person> v;
Person p1("小明",12);
Person p2("小离",20);
Person p3("小军",31);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
//要进行适配才能进行对类内函数操作 mem_fun_ref()
for_each(v.begin(),v.end(),mem_fun_ref(&Person::showPer));
}
int main()
{
test();
return 0;
}
注意点:&Person::showPer 要确定范围,是在类这个作用域下的
然后再给它进行适配mem_fun_ref()
运行结果:
也可以在遍历算法同时,对类内函数中的属性进行增加如例子:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>
//创建类
class Person
{
public:
Person(string name,int age)
{
this->m_name = name;
this->m_age = age;
}
void showPer()
{
cout<<"姓名:"<<m_name<<" 年龄:"<<m_age<<endl;
}
void addPer() //每个人年龄增加1
{
m_age++;
}
string m_name;
int m_age;
};
void test()
{
vector<Person> v;
Person p1("小明",12);
Person p2("小离",20);
Person p3("小军",31);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
//要进行适配才能进行对类内函数操作 mem_fun_ref()
for_each(v.begin(),v.end(),mem_fun_ref(&Person::showPer));
for_each(v.begin(),v.end(),mem_fun_ref(&Person::addPer));
cout<<endl;
for_each(v.begin(),v.end(),mem_fun_ref(&Person::showPer));
}
int main()
{
test();
return 0;
}
运行结果:
如果容器存放的对象是指针,那么用mem_fun()
如果容器存放的对象是实体,那么用mem_fun_ref()