文章目录
- 一、仿函数 functor
- 1、仿函数 functor 简介
- 2、仿函数 functor 调用
- 3、代码示例 - 仿函数 functor 调用
- 二、为自定义类元素设置排序规则 - 仿函数 functor
- 1、自定义类排序规则
- 2、仿函数 - 实现自定义类排序规则
- 3、重载 < 运算符函数 - 实现自定义类排序规则
一、仿函数 functor
1、仿函数 functor 简介
在上一篇博客 【C++】STL 容器 - set 集合容器 ④ ( 设置 set 集合容器的排序规则 | 默认的 set 集合容器 - 从小到大排列 | 设置容器从大到小排列 | 使用仿函数自定义集合排序规则 ) 中 , 引入了 仿函数 概念 , 使用 仿函数 自定义了 set 集合容器的排序规则 ;
set 集合容器 的 排序规则 , 可以使用 函数回调 实现 , 函数回调 可以使用 函数指针 实现 , 但是 C++ 语言中 , 提供了 仿函数 机制 , 可以借助 仿函数 实现 回调函数 ;
仿函数 functor , 又称为 " 函数对象 " , 是一个在许多编程语言中都存在的概念 , 它通常指一个对象 , 该对象能像函数那样被调用 ;
仿函数 是一种特殊的类或结构体 , 它可以重载 ()
运算符以模拟函数调用 , 仿函数也可以像函数一样被调用 ;
2、仿函数 functor 调用
要调用一个 仿函数 functor : 给定如下仿函数 :
struct IntCompare {
bool operator()(const int& a, const int& b) const volatile {
return (a < b); // 降序排序
}
};
- 首先 , 需要创建一个 仿函数类 的 实例对象 ;
// 创建 仿函数对象
IntCompare ic;
- 然后 , 使用 对象名 和 圆括号来调用仿函数 , 就像调用普通函数一样 , 将所需的参数传递给 仿函数对象 进行调用 ;
// 通过 仿函数对象 调用仿函数
bool b = ic(1, 2);
3、代码示例 - 仿函数 functor 调用
在下面的代码示例中 ,
首先 , 定义了一个名为 IntCompare 的仿函数结构体 / 类 , C++ 中结构体就是类 , 该类中重载了 ()
运算符 , 判断传入的 2 个参数的大小 ;
然后,创建了一个 IntCompare 实例对象 ic , 通过该 ic 对象调用 仿函数 ;
代码示例 :
#include "iostream"
using namespace std;
#include "set"
struct IntCompare {
bool operator()(const int& a, const int& b) const volatile {
return (a < b); // 降序排序
}
};
int main() {
// 创建 仿函数对象
IntCompare ic;
// 通过 仿函数对象 调用仿函数
bool b = ic(1, 2);
// 打印 仿函数调用结果
cout << "b = " << b << endl;
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
b = 1
Press any key to continue . . .
二、为自定义类元素设置排序规则 - 仿函数 functor
1、自定义类排序规则
在 set 集合容器中 , 默认情况 使用 <
运算符 对元素进行排序 , 如果集合中的元素没有重载 <
运算符 , 就会出现问题 ;
对于自定义类元素,我们需要提供自定义的排序规则。
如果将 自定义类对象 元素加入到 set 集合容器中 , 并且 该 自定义类 没有重写 <
运算符 , 就会出现崩溃情况 ;
自定义类排序规则 :
- 使用仿函数对比两个 自定义类对象 元素 ;
- 重载自定义类中的 < 运算符 ;
2、仿函数 - 实现自定义类排序规则
代码示例 :
#include "iostream"
using namespace std;
#include "set"
class Student {
public:
int age;
Student(int val) {
this->age = val;
};
};
struct StudentCompare {
bool operator()(const Student& a, const Student& b) const volatile {
return (a.age < b.age); // 降序排序
}
};
int main() {
Student s1(9);
Student s2(5);
Student s3(2);
Student s4(7);
set<Student, StudentCompare> studentSet;
studentSet.insert(s1);
studentSet.insert(s2);
studentSet.insert(s3);
studentSet.insert(s4);
// 遍历 set 集合容器
for (set<Student, StudentCompare>::iterator it = studentSet.begin(); it != studentSet.end(); it++)
{
cout << it->age << " ";
}
// 回车换行
cout << endl;
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
2 5 7 9
Press any key to continue . . .
3、重载 < 运算符函数 - 实现自定义类排序规则
对于自定义类 , 重载 < 运算符函数 ;
之后将 Student 类实例对象 放入 set 集合容器中 , 会自动按照 < 运算符重载函数 进行排序 ;
class Student {
public:
int age;
Student(int val) {
this->age = val;
};
bool operator<(const Student& b) const {
return this->age < b.age;
};
};
代码示例 :
#include "iostream"
using namespace std;
#include "set"
class Student {
public:
int age;
Student(int val) {
this->age = val;
};
bool operator<(const Student& b) const {
return this->age < b.age;
};
};
struct StudentCompare {
bool operator()(const Student& a, const Student& b) const volatile {
return (a.age < b.age); // 降序排序
}
};
int main() {
Student s1(9);
Student s2(5);
Student s3(2);
Student s4(7);
// 如果 Student 类没有重载 < 运算符
// 则必须实现 仿函数 StudentCompare
// set<Student, StudentCompare> studentSet;
// 如果 Student 类重载了 < 运算符
// 可以直接使用该重载运算符函数进行对比
set<Student> studentSet;
studentSet.insert(s1);
studentSet.insert(s2);
studentSet.insert(s3);
studentSet.insert(s4);
// 遍历 set 集合容器
for (set<Student, StudentCompare>::iterator it = studentSet.begin(); it != studentSet.end(); it++)
{
cout << it->age << " ";
}
// 回车换行
cout << endl;
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
2 5 7 9
Press any key to continue . . .