导航

要使用头文件#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;
} 

运行结果:
c++适配器  bind2nd 与 bind1st  取反适配器 not1()  函数指针适配器 ptr_fun  成员函数适配器  mem_fun_ref()或者mem_fun_c++

我们再看下bind2nd 与bind1st的区别:
相同点:两个使用之后结果相同
不同点:两者的绑定参数不一样

对于bind2nd打印下各个参数结果:
c++适配器  bind2nd 与 bind1st  取反适配器 not1()  函数指针适配器 ptr_fun  成员函数适配器  mem_fun_ref()或者mem_fun_ios_02

对于bind1st打印下各个参数结果:
c++适配器  bind2nd 与 bind1st  取反适配器 not1()  函数指针适配器 ptr_fun  成员函数适配器  mem_fun_ref()或者mem_fun_#include_03
结论:可以看到各自在仿函数中的参数绑定的各个值都不相同,结果还是一样的

————————————————————————————————————————

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;
} 

运行结果:
c++适配器  bind2nd 与 bind1st  取反适配器 not1()  函数指针适配器 ptr_fun  成员函数适配器  mem_fun_ref()或者mem_fun_仿函数_04
要是我们使用到取反呢,直接在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;
} 

运行结果:
c++适配器  bind2nd 与 bind1st  取反适配器 not1()  函数指针适配器 ptr_fun  成员函数适配器  mem_fun_ref()或者mem_fun_#include_05

————————————————————————————————————————

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()

运行结果:
c++适配器  bind2nd 与 bind1st  取反适配器 not1()  函数指针适配器 ptr_fun  成员函数适配器  mem_fun_ref()或者mem_fun_ios_06

也可以在遍历算法同时,对类内函数中的属性进行增加如例子:

#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;
} 

运行结果
c++适配器  bind2nd 与 bind1st  取反适配器 not1()  函数指针适配器 ptr_fun  成员函数适配器  mem_fun_ref()或者mem_fun_ios_07

如果容器存放的对象是指针,那么用mem_fun()
如果容器存放的对象是实体,那么用mem_fun_ref()