[STL] function object adapter bin1st, bin2st, not1, not2, ptr_fun, mem_fun, mem_fun_ref (brief notes only if their use)

Function object adapter

Read the following program, compile and run, I believe that we can quickly understand how to use the function object adapters
Here Insert Picture Description

#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
using namespace std;
/*
仿函数适配器:  bin1st bin2st  绑定适配器
仿函数适配器:  not1   not2
仿函数适配器:  ptr_fun
成员函数适配器:mem_fun  mem_fun_ref
*/

struct MyPrint :public binary_function<int,int,void>{////二元:binary_function<int,int,void> 一元:unary_function<int,bool>
	void operator()(int v,int val) const{
		cout << "v: " << v << " val: " << val << endl;
		cout << v +val<< " ";
	}
};

//仿函数适配器:  bin1st bin2st  绑定适配器
void test01() {
	vector<int>v;
	for (int i = 0; i < 10; ++i) {
		v.push_back(i);
	}
	int num = 200;
	for_each(v.begin(), v.end(), bind2nd(MyPrint(),num));
	//绑定适配器 将一个二元的函数对象转变成一个一元的函数对象

	//MyPrint print;//这两种都行
	//for_each(v.begin(), v.end(), print());
/*
bind1st,bind2nd区别?
bind1st,将加入的num 绑定为函数对象的第一个参数
bind2nd,将加入的num 绑定为函数对象的第二个参数

*/
}
//////////////////////////////////////////////////////////////////////////////////////
/*
struct Mycompaper{

	bool operator()(int v, int v1) {
		return v > v1;
	}
};
*/
/////////////////////若其他都不改将输出结果变为从小到大 那么取反需要继承 将上面的Mycompaper进行以下方式改写
struct Mycompaper :public binary_function<int,int,bool>{////二元:binary_function<int,int,void> 一元:unary_function<int,bool>

	bool operator()(int v, int v1) const{
		return v > v1;
	}
};
struct MyPrint02  {
	void operator()(int v)  {
		cout << " " << v ;
	}
};

struct MyGreater5 :public unary_function<int,bool>{////二元:binary_function<int,int,void> 一元:unary_function<int,bool>
	bool operator()(int v)const {
		return v > 5;
	}
};

//仿函数适配器:  not1   not2 取反适配器


void test02() {
	vector<int>v;
	for (int i = 0; i < 10; ++i) {
		v.push_back(i);
	}
	sort(v.begin(), v.end(), Mycompaper());//9 8 7 6 5 4 3 2 1 0
	for_each(v.begin(), v.end(), MyPrint02());
	cout << endl;
	sort(v.begin(), v.end(),not2(Mycompaper()));//加入not2 取反适配器 0 1 2 3 4 5 6 7 8 9
	for_each(v.begin(), v.end(),MyPrint02());
	cout << endl;

/*
not1和not2的区别
二元谓词取反用not2;对一元谓词取反用not1.
*/
	vector<int>::iterator it = find_if(v.begin(), v.end(), MyGreater5());//查找第一个大于5的数据元素
	if (it == v.end()) {
		cout << "未找到" << endl;
	}
	else {
		cout << *it << endl;
	}
	vector<int>::iterator it1 = find_if(v.begin(), v.end(), not1(MyGreater5()));//查找第一个小于5的数据元素
	if (it1 == v.end()) {
		cout << "未找到" << endl;
	}
	else {
		cout << *it1 << endl;
	}

}
/////////////////////////////////////////////////////////////////////////////////////////////
//仿函数适配器:  ptr_fun
void Myprint03(int val, int val2) {//如果需要改该函数绑定参数是没有办法的 因此看test03中:
	
	cout << "val1:" << val<<" val2:"<<val2<<endl;
}

void test03() {
	vector<int>v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	//回答以上问题:ptr_fun把普通函数适配(转成)成函数对象ptr_fun(Myprint03)这就把函数变成函数对象了,就可以进行参数绑定
	//for_each(v.begin(), v.end(), ptr_fun(Myprint03));//此时可以绑定
	for_each(v.begin(), v.end(), bind2nd(ptr_fun(Myprint03), 100));
}
/////////////////////////////////////////////////////////////////////////
//成员函数适配器:mem_fun  mem_fun_ref
class Person {
public:
	Person(int age, int id) :age(age), id(id) {}
	void show() {
		cout << "age:" << age << " id:" << id << endl;
	}
public:
	int age;
	int id;
};

void test04() {
	//如果容器中存放的对象或者对象指针,我们for_each算法打印的时候,调用类自己提供的打印函数。
	vector<Person>v;
	Person p1(10, 20), p2(30, 40), p3(50, 60);
	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::show));//用成员函数打印
	cout << endl;

	vector<Person*>v1;
	v1.push_back(&p1);
	v1.push_back(&p2);
	v1.push_back(&p3);
	for_each(v1.begin(), v1.end(), mem_fun(&Person::show));
/*
men_fun_ref和men_fun区别?
如果存放的是指针使用 men_fun;
如果使用的是对象 使用mem_fun_ref;

*/

}

int main(void) {
	//test01();
	//test02();
	//test03();
	test04();
	return 0;
}
Published 57 original articles · won praise 28 · views 4122

Guess you like

Origin blog.csdn.net/weixin_41747893/article/details/102960571