C++学习28:仿函数深度探索、仿函数适配器

仿函数是STL六大部件部件中最简单的。所谓仿函数就是一个类里面重载小括号,用这个类创造的对象就是仿函数对象。仿函数只为算法服务,给算法以独特的准则

1 仿函数简介

1.1 特征

仿函数必须重载圆括号。

1.2 分类

1、算术类:进行加减运算的;
2、逻辑运算类:对比特位进行操作的;
3、相对关系类:比大小。
在这里插入图片描述

1.3 示例

单纯仿函数的示例如下:
在这里插入图片描述
融入了算法的仿函数示例如下(以sort为例):
在这里插入图片描述
其中第1个是默认的排序算法类型,第2个使用了一个函数作为排序类型,第3个用了定义出的一个行为像函数的类(自己定义的仿函数)对象来作为排序类型,而前三个并不是仿函数。第4个和第5个使用了仿函数类型,且后面加上了小括号,即传入的应该是临时对象。

2 仿函数适配器

2.1 STL仿函数继承的父类

自己定义的仿函数是没有继承关系的,是没有融入STL的;而标准库的仿函数都继承了特定的几个类。
unary_function表示有一个操作数,如一个数的取反操作。
binary_function表示有两个操作数,如两个数的比大小操作。
这种STL的仿函数接受模板操作,所继承的类没有数据,也没有函数。
在这里插入图片描述
仿函数的可适配条件就是要让各部分合适的继承父类。如适配器要问问题,如binary_function第二参数是什么,就需要仿函数来回答,要回答问题就必须必须继承某一个。因此如同算法问问题迭代器回答一样,STL的仿函数也要回答适配器的问题。
所以自己想创造仿函数,要选择适当的某一个父类来继承。

2.2 三个重要的typedef

仿函数想要被适配,需要回答问题,方法是继承一个父类,父类回答问题的方式是typedef。
在这里插入图片描述
如上图,在上面2中提出了关于进行回答问题的typedef:
关于less< int >的定义:
在这里插入图片描述
仿函数的对象,必须能够回答三个问题,才能与适配器进行搭配:
1、Operation::first_arguement_type:第一参数类型是否合理(能否转换成int)
2、Operation::second_arguement_type:第二参数类型是否合理(能否转换成int)
3、Operation::result_type:返回类型是否合理(能否转换成bool)
例子见下面3.1。

3 仿函数适配器示例

在STL第一讲的示例中就出现了两个仿函数适配器,下面对这两个适配器进行讲解。

3.1 binder2nd

绑定第二参数,将第二参数绑定为40,仿函数less是比小,用小括号得到一个临时对象,故使用binder2nd绑定40,即作用是比40小。
在这里插入图片描述
对外界的接口是bind2nd,提供类名Operation,也就是仿函数,把这个仿函数的类型传给内部函数,内部调用函数为binder2nd。这里绿色的op是一个操作,带上了小括号代表是仿函数less< int >的临时对象,绿色的value将记录另一个对象40。最后返回的是调用op把一个值根据第二参数变成了两个值比较,即less函数,并且将less比大小的数据定为与40比较。

关于上文的typedef:如Operation::second_arguement_type,这里要问第二参数,回答为value,即40,若40可以转化为Operation的类型int,则能够回答,否则会出现error!running time error!同理,x必须是Operation::first_arguement_type类型的东西,这里less< int >能够回答。例子中返回类型需要是pred,故op操作得到的对象也必须是个bool类型。

3.2 not1

继续修饰上面的binder2nd后的东西。本来是为了得到“小于40”,但加了not1,得到的就是“大于40”了。故not1功能是取反。
在这里插入图片描述
如上例,过程同binder2nd,下面来宏观看一下:首先进行函数模板的实参推导,即Predicate的类型被推导;然后返回一个临时对象unary_negate< Predicate >(pred),故调用其构造函数,传入函数中,将x记在pred中,通过对小括号的操作符重载进行取反操作。具体顺序请参考图上箭头。

3.3 bind(新)

使用新的名字(下图左列)来取代旧的(下图右列):
在这里插入图片描述
可以绑定任意数量的实参,具体功能如下例:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值