1.可调用对象
什么是可调用对象主要有以下几种:
函数指针:
仿函数:
可转换为函数指针的类对象:
类成员函数指针或者类成员指针:
(注释:框里的的写法和上面一样效果)
上面的几个满足条件的可调用对象对应的类型被统称为可调用类型,现在,c++11通过提供
std::function 和std::bind统一了可调用对象的各种操作。
2.可调用对象包装器
std::function是可调用对象的包装器,他是一个类模板,可以容纳处理类成员(函数)指针之外的所有可调用对象,通常指定他的模板参数,它可以用统一的方式处理函数、函数对象、函数指针、并允许保存和延迟执行他们。
2.1基本用法
std::funtion必须要包含一个叫functional的头文件,其语法如下:
#include <functional>
std::function<返回值类型(参数类型列表)>diy_name = 可调用对象;
示例:
通过测试:srd::function可以将可调用对象进行包装,得到一个统一的格式,包装完成得到的对象相当于一个函数指针,和函数指针的使用方式相同,通过包装器对象就可以完成对包装函数的调用了。
2.2作为回调函数使用
回调函数示例:
由上述可以看出使用std::function可以非常方便的将仿函数转化为一个函数指针,通过函数指针的传递,在其他函数的合适的位置就可以这个包装好的仿函数。
std::function作为函数的传入参数,可以将定义方式不同的可调用对象进行统一的传递,大大增加程序的灵活性。
3.绑定器
std::bind用来将可调用对象与其参数一起进行绑定。绑定后结果可以使用std::function进行保存,并延迟调用到任何我们需要的时候,主要有两大作用:
- 将可调用对象与其参数一起绑定成一个仿函数。
- 将多元(参数个数为n,n>1)可调用对象转换为一元或者(n-1)元可调用对象,即只绑定部分参数。
绑定器格式介绍:
//绑定非类成员函数/变量
auto f = std::bind(可调用对象地址,绑定的参数/占位符);
//绑定类型成员函数/变量
auto f = std::bind(类函数/成员地址,类实例对象地址,绑定的参数/占位符);
示例:
std::bind绑定器返回的是一个仿函数类型,得到的返回值可以直接赋值给一个std::function,在使用的时候我们并不需要关心绑定器的返回值类型,使用auto进行自动类型推导就可以了。
其实placehoders::_1是一个占位符,代码这个位置将在调用函数时被传入的第一个参数所替代,同样还有其他占位符placeholders::_2、 placeholders::_3、placeholders::_4......等。
有了占位符可以使得std::bind变得更加灵活。
由图可以看出,std::bind可以直接绑定函数的所有参数,也可以仅绑定部分的参数。在绑定部分参数的时候,通过使用std::placeholders来决定空位参数将会属于调用发生时的第几个参数。
可调用对象包装器std::function是不能实现对类成员函数指针或类成员指针的包装的,但是通过std::bind的配合之后,就可以完美的解决这个问题,示例如下:
在绑定器绑定类成员函数或者成员变量的时候需要将他们所属的示例对象一并传递到绑定器函数内部,f1的类型是function<void (int, int)>,通过std::bind将Test的成员函数output的地址和对象t绑定,并转化为一个仿函数并存储到对象f1中。f2同理。
上述中可以直接配合auto使用自动推导更容易。
------------------------------------------------------------
上述如有错误欢迎大家指正。