文章目录
- 1. 包装器
- 概念理解
- 用法
- 成员函数的包装
- 静态成员函数
- 非静态成员函数
- 2. bind
- 概念理解
- 功能1 调整参数顺序 (用处不大)
- 功能2 调整参数个数
1. 包装器
概念理解
function包装器 也被叫做 适配器
C++11中function本质是类模板,也是一个包装器
意义在于 对可调用对象类型进行封装再适配
可调用对象:函数指针 / lambda / 仿函数
用法
需要包含 头文件 functional
模板参数
Ret : 被调用函数的返回类型
…Args作为参数包,这个参数包中包含0到任意个模板参数
Args… :被调用函数的形参
f作为函数指针,Functor作为一个类 ,两者类型是完全不同的,
想要声明出统一的类型,就需要借助包装器进行包装,从而适配出统一的可调用对象的类型
function<int(int,int)>
第一个int作为返回值 小括号中的两个int参数,作为被调用函数的参数
此时既可以使用函数指针进行初始化,也可以使用仿函数进行初始化
对于产生的包装器对象v1和v2,两者的类型是相同
但在调用时,一个调用的是f函数,一个调用的是Functor中的operator()
包装器作为map的第二个参数
包装器的返回值为int类型,被调用函数有两个int的参数
可以将 f (函数指针) 、 Functor (仿函数)、 lambda表达式 作为可调用对象 传给包装器 ,对包装器进行初始化
成员函数的包装
成员函数中分为静态成员函数和非静态成员函数
静态成员函数
对于静态成员函数,可以直接使用包装器 function
通过Plus这个类去寻找到plusi 这个函数 ,对包装器 进行初始化即可
非静态成员函数
对于普通成员函数,是没办法直接使用 function包装器的
普通成员函数在类中有 this指针存在, 所以要在main函数中要加入 Plus
这里不是直接去调用plusd这个函数的, 而是通过Plus对象去调用 plusd
这里不是直接去调用plusd这个函数的, 而是通过指针去调用 plusd
若为plus*,则匿名对象是需要取地址的
而匿名对象属于右值,不能取地址 ,
所以使用Plus*,不能使用匿名对象
最后加入&后, 即可解决 问题 (加&是规定)
2. bind
概念理解
bind函数 定义在头文件中,是一个函数模板
bind函数可以看作一个通用的函数适配器,它接受一个可调用对象(函数指针 仿函数 lambda对象)
生成一个新的可调用对象来 适应 原对象的参数列表
调用bind的一般形式:auto newCallable = bind(callable,arg_list);
arg_list中的参数可能包含形如_n的名字,其中n是一个整数,这些参数是占位符,
_1表示第一个参数,_2表示第二个参数 ,但默认情况下获取不到 (_1 和_2被放到命名空间中)
绑定的参数被放到 placeholders 中
placeholders 命名空间中,有_1 _2 _3等 符号存在
所以想使用_1表示第一个参数 ,需在placeholders命名空间中访问_1 即 placehlders::_1
功能1 调整参数顺序 (用处不大)
正常情况下,把1传给参数a,把2传给参数b ,打印a=1 b=2
若想把1传给参数b,把2传给参数a ,则使用bind
bind的第一个参数为可调用对象
bind的参数包作为占位符,借助placeholders 命名空间 来访问里面的字符(_1 _2)
把Sub1函数中的第二个参数2传给Sub函数的a
把Sub1函数中的第一个参数1传给Sub函数的b
绑定后 会返回一个可调用对象, 可以选择使用auto 自动推导类型
再通过返回的对象,再次调用1 2 ,则结果不同
功能2 调整参数个数
在Sub类中的 func函数,虽然看似只有两个参数,但是还有一个隐藏的this指针存在
若使用包装器,则需三个参数,通过匿名对象去调用func函数
function中的参数个数与 func的参数个数 不同
若想两者参数个数相同,则需要绑定,进行调整参数的个数
bind可以把某个参数绑死 (把其中一个参数显示传过去)
把匿名对象显示传过去,此时匿名对象就绑死了
placehlders::_1和 placehlders::_2 表示剩下的两个参数
可调用对象 只需 传递两个参数 即可