C++可调用对象包装器:std::function探析
在C语言的时代,我们可以使用函数指针来吧一个函数作为参数传递,这样我们就可以实现回调函数的机制,例如我们编写一个函数f
,将函数do_sth
作用于x1
,x2
两个变量,并返回得到作用的结果:
int f( do_sth, x1,x2);
f的返回值将回依据传入函数do_sth
的不同而得到不同的结果,例如x1
与x2
要进行四则运算,则只需要将do_sth
分别传入为加减乘除四个运算函数即可。
然而,函数的定义方法却五花八门,可以定义为函数,也可以定义成函数对象类,这样就导致使用统一的方式保存可调用对象或者传递可调用对象时,会十分繁琐。
// 普通函数 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,即
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前,需要#include <functional>
带上头文件 。 通过std::function
对C++中各种可调用实体(普通函数、lambda表达式、函数指针、以及其它函数对象等)的封装,形成一个新的可调用的std::function
对象;让我们不再纠结那么多的可调用实体。