C++之函数适配器

函数适配器

头文件:functional 系统仿函数和适配器头文件

一、定义

函数对象适配器是完成一些配接工作,这些配接包括绑定(bind),否定(negate),以及对一般函数或成员函数的修饰,使其成为函数对象。

绑定器:

bind1st 将参数绑定为二元函数对象的第一个参数。			操作的可调用对象,必须是仿函数
bind2nd 将参数绑定为二元函数对象的第二个参数。			操作的可调用对象,必须是仿函数
bind 将参数绑定为n元函数对象的,第n个参数。				操作的只要是可调用对象即可

求反器:

 not1 对一元函数对象取反								操作的可调用对象,必须是仿函数
 not2 对二元函数对象取反								操作的可调用对象,必须是仿函数

成员函数适配器:

mem_fun 把成员函数转成仿函数							容器里存的是对象指针
mem_fun_ref 修饰成员函数  							容器里存的是对象)

二、绑定器实现

bind1st绑定到第一个参数
bind2nd 绑定到第二个参数

注意:这个两个函数只能 用来绑定仿函数,普通函数不行
自定义的仿函数,还必须从系统定义的一个类继承

一个参数的仿函数从:unary_function
二个参数的仿函数从:binary_function

1、bind2nd和bind1nd的代码实现

struct CTest :public binary_function<int, int, void> 
{ 
	void operator()(int i, int val) const 
	{ 
		cout << i << " + " << val << " = " << i + val << endl; 
	} 
}; 
void obj3() 
{
	vector<int> v = { 9,8,7,6,5,1,2,3,4 }; 
	//bind2nd和bind1nd过程一样
	for_each(v.begin(), v.end(), bind2nd(CTest(), 10));
	//for_each(v.begin(), v.end(), bind1st(CTest(),10)); 
}

2、bind也是绑定参数,只要是可调用对象,都可以绑定,不在局限于仿函数(函数对象)

std::bind返回一个基于Func的函数对象,其参数被绑定到Args上。 f的参数要么被绑定到值,要么被 绑定到placeholders(占位符,如_1, _2, …, _n)。

参数:
Func:一个可调用对象(可以是函数对象、函数指针、函数引用、成员函数指针、数据成员指
针…),它的参数将被绑定到args上。
Args:绑定参数列表,参数会被值或占位符替换,其长度必须与f接收的参数个数一致。

使用2种:
改变参数个数 和 改变行参顺序。

#include 
#include 
#include 
#include
using namespace std;

bool compare(int a, int b)
{
	return a > b;
}
void show(int a, int b, int c)
{
	cout << a << "++++" << b << "++++" << c << endl;
}
int main()
{
	
	vector<int> A = { 1,2,3,4,5,6,7,8,9,10 };
	//统计比0大的数的个数
	auto x=count_if(A.begin(), A.end(), std::bind(compare,std::placeholders::_1,0));
	cout << x << endl;
	//改变位置
	//auto自动推到类型 返回值是与函数类型一致
	auto ss = std::bind(show, std::placeholders::_2, std::placeholders::_1, 0);
	//std::placeholders::_2, std::placeholders::_1为只不一样会将参数1和二的位置交换
	ss(1, 2, 3);
	system("pause");
	return 0;
}

三、成员函数适配器

mem_fun
把类的成员函数转成仿函数


class Person
{
public:
	Person(int age, int id) :_age(age), _id(id) {} 
	
	void show()
	{
		cout << "id: " << _id << "age: " << _age << endl;
	} 
private:
	int _age; int _id;
}; 
void fun_cref()
{ 
	Person p1(1, 2), p2(3, 4), p3(5, 6); 
	vector< Person*> v = { &p1,&p2,&p3 }; 
	for_each(v.begin(), v.end(), mem_fun(&Person::show));
}

mem_fun_ref
同上,把类的成员函数转成仿函数

class Person
{ 
public: 
	Person(int age, int id) :_age(age), _id(id) {} 

	void show() 
	{ 
		cout << "id: " << _id << "age: " << _age << endl; 
	}
private: 
	int _age; 
	int _id; 
}; 
void fun_cref() 
{	
	Person p1(1, 2), p2(3, 4), p3(5, 6);
	vector< Person> v = { p1,p2,p3 };
	for_each(v.begin(), v.end(), mem_fun_ref(&Person::show));
}

两者区别

当容器中存的是对象时使用mem_fun_ref
存放的是对象的指针时使用mem_fun

你可能感兴趣的:(c++,c++)