目录
1、什么是仿函数?
2、仿函数在哪里?
3、如何理解?(很简单很简单)
4、仿函数的价值,应用场景:
1、商品的比较
2、成绩的比较
1、什么是仿函数?
仿函数仿函数,顾名思义就是模仿函数
模仿了函数的什么呢?
模仿了函数的调用形式
例如有一个函数int func(v)
调用的时候是 func(v1)
func(v1)这个就是函数的调用方式
//这就是一个仿函数,是一个类,类内部封装了一个括号操作符重载
template<class T>
class A
{
public:bool operator()(const T& x, const T& y){return x > y;}
};
2、仿函数在哪里?
仿函数在类内部
本质就是一个运算符重载
不过重载的是一个 boo operator(){...}
例如类型A,内部重载了一个运算符:boo operator(){...}
那么,A的对象在调用方式时,其形式为:
1、a1.operator()(操作数);
A<int> a;//调用方式1a.operator()(1,2);
2、a1(操作数);
//调用方式2a(1, 2);
3、A()(操作数);
//如果调用方式3,你看不明白,那下面这个就很好理解了//事实上是这样的:匿名对象A<int>() (1, 2);
第二种调用形式是不是和函数的调用方式一样?因此,叫将A叫做仿函数。
3、如何理解?(很简单很简单)
其实就是编译器的一个编译优化的问题
我们可以类比vector的[]运算符重载
1、本来的方括号【】和括号()操作符调用方式
A<int> a;std::vector<int> v;//1、这是[]方括号操作符本来应该的调用方式v.operator[](2);//同理,这也是()括号操作符本来应该的调用方式a.operator()(1, 2);
2、省略了operator之后的调用方式
//2、但是编译器进行了优化//直接省略了.operator[]v[2];//同理,也是直接省略了.operator()a(1,2);
因此,在省略之后了调用方式上,看起来,就像是一个函数a的调用。
但是事实上不是,a其实是一个类的是实例化对象
这个实例化对象a调用了内部的()重载括号操作符
但是,编译器的优化效果,使得我们可以省略去operator显式调用
于是,在视觉的效果上,就只剩下了a()
所以,看起来像一个函数调用,,因而叫做仿函数
但是,要记住,其底层依旧是a.operator()()
再次重申:
仿函数本质就是一个类
类对象调用a.operator()()被编译器优化省略了
优化成为了a()
看起来像函数
但其实不是函数
所以叫做仿函数
(我觉得,已经讲的足够清楚了,仿函数知道这些就足够了,至于适配器,后面再讲)
4、仿函数的价值,应用场景:
1、商品的比较
默认一个类内部只能实现一个比较逻辑,也就是对单一的变量进行比较
例如比较运算符比较了价格,就不能比较评分、质量等其他标准
所以,就用到了仿函数
2、成绩的比较
比较往往需要的不仅仅是一个结果
例如说,对成绩进行排名,你得知道到底是张三倒数第一,还是李四倒数第一
如果仅仅排出成绩的序列,但是不知道到底是谁的成绩,那么毫无意义
所以,仅仅是对某个数据的比较,然后返回一个单一的结果是不行的
返回值一定是一个自定义类型
我们可以控制返回值来控制上述的返回结果
所以,仿函数又用到了
仿函数的大于是降序,小于是升序;别问,问就是语法规定