std::function 必须要包含一个叫做 functional 的头文件,可调用对象包装器使用语法如下:
#include <functional>
std::function<返回值类型(参数类型列表)> diy_name = 可调用对象;
下面的实例代码中演示了可调用对象包装器的基本使用方法:
#include <iostream>
#include <functional>
using namespace std;
int add(int a, int b)
{
cout << a << " + " << b << " = " << a + b << endl;
return a + b;
}
class T1
{
public:
static int sub(int a, int b)
{
cout << a << " - " << b << " = " << a - b << endl;
return a - b;
}
};
class T2
{
public:
int operator()(int a, int b)
{
cout << a << " * " << b << " = " << a * b << endl;
return a * b;
}
};
int main(void)
{
// 绑定一个普通函数
function<int(int, int)> f1 = add;
// 绑定以静态类成员函数
function<int(int, int)> f2 = T1::sub;
// 绑定一个仿函数
T2 t;
function<int(int, int)> f3 = t;
// 函数调用
f1(9, 3);
f2(9, 3);
f3(9, 3);
return 0;
}
结果:
9 + 3 = 12
9 - 3 = 6
9 * 3 = 27通过测试代码可以得到结论:std::function 可以将可调用对象进行包装,得到一个统一的格式,包装完成得到的对象相当于一个函数指针,和函数指针的使用方式相同,通过包装器对象就可以完成对包装的函数的调用了。
作为回调函数使用
因为回调函数本身就是通过函数指针实现的,使用对象包装器可以取代函数指针的作用,来看一下下面的例子:
#include <iostream>
#include <functional>
using namespace std;
class A
{
public:
// 构造函数参数是一个包装器对象
A(const function<void()>& f) : callback(f)
{
}
void notify()
{
callback(); // 调用通过构造函数得到的函数指针
}
private:
function<void()> callback;
};
class B
{
public:
void operator()()
{
cout << "我是要成为海贼王的男人!!!" << endl;
}
};
int main(void)
{
B b;
A a(b); // 仿函数通过包装器对象进行包装
a.notify();
return 0;
}
通过上面的例子可以看出,使用对象包装器 std::function 可以非常方便的将仿函数转换为一个函数指针,通过进行函数指针的传递,在其他函数的合适的位置就可以调用这个包装好的仿函数了。
另外,使用 std::function 作为函数的传入参数,可以将定义方式不相同的可调用对象进行统一的传递,这样大大增加了程序的灵活性。