c++11中新增了包括器functional,其目的是为了统一不同的可调用对象的各种不同的操作。
可调用对象又分为四种:
- 函数指针
- 具备operator()成员函数的类对象(仿函数)
- 可被转换为函数指针的对象
- 类成员(函数)指针闭包
std::function是一个类模板,能容纳类成员(函数)指针意外的全部可调用对象。经过指定它的模板参数,它能够用统一的方式处理函数、函数对象、函数指针,并容许保存和延时执行它们。
格式:
std::function<返回值(参数)>f
#include <functional>
int test_function(int a, int b) {
return a + b;
}
int main() {
std::function<int(int, int)> f2;
f2 = test_function; // 这里 f2 接收的是函数指针, 其他的可调用对象,都是同样的方式
num = f2(3, 4);
cout << "f2:" << num << endl;
return 0;
}
- 匿名函数就可以用function来接收函数,不过一般用auto
可调用对象包装器std::function是不能实现对类成员函数指针或者类成员指针的包装的,但是通过绑定器std::bind的配合之后,就可以实现这个操作
bind
std::bind用来将可调用对象与其参数一块进行绑定,绑定后的结果能够使用std::function进行操作,并延迟调用到任何咱们需要的时候。
这样就大大增加了可调用对象的灵活度。
通俗来讲,它主要有两大作用:
- 将可调用对象与其参数一起绑定成一个仿函数。
- 将多元(参数个数为n, n>1)可调用对象转换为一元或者(n-1)元可调用对象,即只绑定部分参数。
语法格式如下:
## 非类成员函数
std::bind(可调用对象地址,绑定的参数/占位符);
## 类成员函数
std::bind(类函数/成员地址,类对象,绑定的参数/占位符);
例子:
#include <iostream>
#include <functional>
using namespace std;
class A {
public:
A(){};
int add_x_y(int a, int b) {
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return a + b;
}
};
int main() {
A a;
auto f = bind(&A::add_x_y, a, 1, placeholders::_1);
// 1 表示第一个实参, placeholders::_1 占位符, 表示函数调用的时候的第一个参数,作为第二个实参
int num = f(2);
cout << "f:" <<num << endl; // a = 1, b = 2
auto f1 = bind(&A::add_x_y, a, placeholders::_1, placeholders::_2);
num = f1(2, 3);
cout << "f1:" << num << endl; // a = 2, b = 3
return 0;
}
placeholders::_1是一个占位符,代表这个位置将在函数调用时被传入的第一个参数所代替。同样还有其他的占位符placeholders::_2、placeholders::_3、placeholders::_4、placeholders::_5等