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



