一、可调用对象
- 一个函数指针
- 一个具有operator()成员函数的类的对象
- 可被转换成函数指针的类对象
- 一个类成员函数指针
C++中可调用对象虽然都有一个比较统一的操作形式,但是定义方法五花八门,这样就导致使用统一的方式保存可调用对象或者传递可调用对象时,十分繁琐。因此提供了std::function和std::bind统一了可调用对象的各种操作。
不同类型可能具有相同的调用形式,如:
// 普通函数
int add(int a, int b){
return a+b;}
// lambda表达式
auto mod = [](int a, int b){
return a % b;}
// 函数对象类
struct divide{
int operator()(int denominator, int divisor){
return denominator/divisor;
}
};
上述三种可调用对象虽然类型不同,但是共享了一种调用形式:
int(int ,int)
std::function就可以将上述类型保存起来,如下:
std::function<int(int ,int)> a = add;
std::function<int(int ,int)> b = mod ;
std::function<int(int ,int)> c = divide();
二、std::function
- std::function 是一个可调用对象包装器,是一个类模板,可以容纳除了类成员函数指针之外的所有可调用对象,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。
- 定义格式:std::function<函数类型>。
- std::function可以取代函数指针的作用,因为它可以延迟函数的执行,特别适合作为回调函数使用。它比普通函数指针更加的灵活和便利。
三、std::bind
可将std::bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。std::bind将可调用对象与其参数一起进行绑定,绑定后的结果可以使用std::function保存。
std::bind主要有以下两个作用:
- 将可调用对象和其参数绑定成一个仿函数
- 只绑定部分参数,减少可调用对象传入的参数
3.1 std::bind()绑定普通函数
double my_divide (double x, double y) {
return x/y;}
auto fn_half = std::bind (my_divide,_1,2);
std::cout << fn_half(10) << '\n'; //输出5
- bind的第一个参数是函数名,普通函数做实参时,会隐式转换成函数指针。因此std::bind (my_divide,_1,2)等价于std::bind (&my_divide,_1,2)
- _1表示占位符,位于中,std::placeholders::_1表示参数的顺序,这里指定了第一个参数的位置在第一位,第二位给出了默认值,这样就减少了一个调用对象传入的参数。
3.2