C++仿函数篇

一:引入

(一):for_each函数

头文件:algorithm
for_each函数用于逐个遍历容器中的元素,它对迭代器中[.begin(),.end())中的每一元素调用子进程函数。
函数原型:
在这里插入图片描述
示例:

#include<iostream>
#include<algorithm>
using namespace std;
void print(int data)
{
	cout << data << "\t";
}
void add(int& data)
{
	data += 10;
}
int main()
{
	//1.for_each(iterator begin,iterator end,函数指针);
	//_Fn for_each(_InIt _First, _InIt _Last, _Fn _Func)  对每一[_First,_Last)元素调用子进程_Func
	int array[] = { 1,2,3,4,5,6,7,8,9,10 };
	//函数名:函数指针
	for_each(array + 0, array + 10, print);//遍历元素并打印
	for_each(array + 0, array + 10, add);//遍历元素,进行批量操作
	cout << endl;
	for_each(array + 0, array + 10, print);//遍历元素并打印

	return 0;
}

(二):sort排序算法

头文件:algorithm

#include<iostream>
#include<algorithm>
using namespace std;
/*
	sort:默认从小到大进行排序
	两个内置的比较准则:
	less<type> 从小到大进行排序
	greater<type> 从大到小进行排序
*/
void print(int data)
{
	cout << data << "\t";
}
int main()
{
	//排序算法 sort
	int array[] = { 10,5,9,4,2,6,7,8,3,1 };
	sort(array + 0, array + 10);//默认的是从小到大排序
	cout << "默认从小到大排序" << endl;
	for_each(array + 0, array + 10, print);
	cout << endl;

	//排序准则				从小到大:less<type>	从大到小:greater<type>
	//添加排序准则进行排序:
	sort(array + 0, array + 10, less<int>());
	cout << "排序准则:从小到大(less<type>)" << endl;
	for_each(array + 0, array + 10, print);
	cout << endl;

	sort(array + 0, array + 10, greater<int>());
	cout << "排序准则:从大到小(greater<type>)" << endl;
	for_each(array + 0, array + 10, print);
	cout << endl;

	return 0;
}

二:仿函数

sort操作自定义类型:

//自定义类型:
struct student
{
	student(string name, int age, int num) :name(name), age(age), num(num) {}
	string name;
	int age;
	int num;
};

由于自定义类型没有排序准则,sort是无法直接对自定义类型进行排序的
那么我们怎解决呢?

(一):重载运算符

在结构体外部进行重载
注意:如果使用了less和greater,则大于号和小于号的重载一定要放到结构体的外部进行

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct student
{
	student(string name, int age, int num) :name(name), age(age), num(num) {}
	string name;
	int age;
	int num;
};
//这里的大于号和小于号的重载需要在结构体外部进行,才能使用less,greater比较准则 因为:const属性没有this指针
bool operator<(student Object1, student Object2)//重载 <
{
	return Object1.name < Object2.name;
}

bool operator>(student Object1, student Object2)//重载 >
{
	return Object1.name > Object2.name;
}

void printStudent(student stu)
{
	cout << stu.name << " " << stu.age << " " << stu.num << endl;
}
int main()
{
	//自定义类型
	student stu[3] = { student("name1",18,1001),student("name3",15,1002),student("name2",23,1003) };
	cout << "正常打印" << endl;
	for_each(stu + 0, stu + 3, printStudent);
	
	sort(stu + 0, stu + 3);
	cout << "重载运算符 < 进行排序,使用sort的默认排序规则(从小到大)" << endl;
	for_each(stu + 0, stu + 3, printStudent);	

	sort(stu + 0, stu + 3,less<student>());
	cout << "重载运算符 < 进行排序,使用less比较准则" << endl;
	for_each(stu + 0, stu + 3, printStudent);

	sort(stu + 0, stu + 3, greater<student>());
	cout << "重载运算符 > 进行排序,使用greater比较准则" << endl;
	for_each(stu + 0, stu + 3, printStudent);


	return 0;
} 

如果使用sort的默认排序方式,不使用比较准则less和greater,我们可以重载小于号 <(只能重载小于号,不能是大于号),这里的重载放到结构体内部外部都可。

(二):仿函数操作

通过前面对sort函数的了解,sort中有两个内置的比较准则可供选择(操作基本数据类型时)。
然而当sort函数操作自定义类型时,我们需要建立一个比较准则

仿函数头文件:functional
仿函数不是函数而是类,正是由于重载了括号使得,类可以像函数形式一样去加括号使用

#include<functional>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct student
{
	student(string name, int age, int num) :name(name), age(age), num(num) {}
	string name;
	int age;
	int num;
	bool operator>(student Object)
	{
		return this->name > Object.name;
	}
};
//普通函数的比较准则
bool sortByAge(student Object1, student Object2)
{
	return Object1.age < Object2.age;
}
bool sortByNum(student Object1, student Object2)
{
	return Object1.num < Object2.num;
}
//仿函数		建立比较准则
template<typename type>
class sortRule
{
public:
	bool operator()(type a, type b)//仿函数必定是要重载括号运算符的
	{
		return a > b;
	}
};
void printStudent(student stu)
{
	cout << stu.name << " " << stu.age << " " << stu.num << endl;
}
int main()
{
	//自定义类型
	student stu[3] = { student("name1",18,1001),student("name3",15,1002),student("name2",23,1003) };
	cout << "正常打印" << endl;
	for_each(stu + 0, stu + 3, printStudent);
	

	sort(stu + 0, stu + 3, sortRule<student>());
	cout << "仿函数名字从小到大" << endl;
	for_each(stu + 0, stu + 3, printStudent);

	sort(stu + 0, stu + 3, sortByAge);
	cout << "调用子进程通过age排序从小到大" << endl;
	for_each(stu + 0, stu + 3, printStudent);

	sort(stu + 0, stu + 3, sortByNum);
	cout << "调用子进程通过num排序从小到大" << endl;
	for_each(stu + 0, stu + 3, printStudent);

	return 0;
} 

三:仿函数批量操作数据

#include<iostream>
#include<string>
#include<functional>
#include<algorithm>
using namespace std;
class modify
{
public:
	modify() :sum(0) {}
	void operator()(int& elem)//修改其值,这里要传引用
	{
		elem += 10;
		sum += elem;
	}
	void value()
	{
		cout << "sum:" << sum << endl;
	}
private:
	int sum;
};
void print(int value)
{
	cout << value << "\t";
}
int main()
{

	//for_each返回的是反函数的对象
	int score[] = { 59,69,34,87,74,23,66,67,56,34 };
	//批量处理
	modify object = for_each(score + 0, score + 10, modify());//类模仿函数的行为
	object.value();//打印总和
	for_each(score + 0, score + 10, print);	
	cout << endl;
	return 0;
}
发布了57 篇原创文章 · 获赞 12 · 访问量 3296

猜你喜欢

转载自blog.csdn.net/weixin_44795839/article/details/104215301