C++可调用对象包装器:std::function探析

C++可调用对象包装器:std::function探析

在C语言的时代,我们可以使用函数指针来吧一个函数作为参数传递,这样我们就可以实现回调函数的机制,例如我们编写一个函数f,将函数do_sth作用于x1,x2两个变量,并返回得到作用的结果:

int f( do_sth, x1,x2);

f的返回值将回依据传入函数do_sth的不同而得到不同的结果,例如x1x2要进行四则运算,则只需要将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对象;让我们不再纠结那么多的可调用实体。

参考来源 & 延伸阅读

  1. std::function::function
  2. C++11 中的std::function和std::bind
  3. C++ 之std::function() 作为函数参数入口 详解
  4. C++服软C#系列 —— std::function
  5. std::function (各类调用实体在模板中的用法)

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注