C++ 使用std::function

1. 关于std::function()

在C语言的时代,我们可以使用函数指针来吧一个函数作为参数传递,这样我们就可以实现回调函数的机制。到了C++11以后在标准库里引入了std::function模板类,这个模板概括了函数指针的概念

函数指针只能指向一个函数,而std::function对象可以代表任何可以调用的对象,比如说任何可以被当作函数一样调用的对象。

当你创建一个函数指针的时候,你必须定义这个函数签名(表征这个函数的入参,返回值等信息);同样的,当你创建一个std::function对象的时候,你也必须指定它所代表的可调用对象的函数签名。这一点可以通过std::function的模板参数来实现。

举个例子来说,如果要定义一个std::function对象func,这个对象可以表示任何有如下函数签名的可调用对象的,

bool(const std::unique_ptr<Widget>)&,     // C++11里面用来比较两个
const std::unique_ptr<Widget>&)   //std::unique_ptr<Widget>对象的函数签名

你可以这么写,

std::function<bool(const std::unique_ptr<Widget>&, 
                     const  std::unique_ptr<Widget>&)> func;

这是因为lambda表达式产生了可调用的对象,这个对象这里称做一个闭包(closure),可以保存在std::function对象里面。
closure(闭包)的定义是,一个函数和它所引用的非本地变量(非lambda表达式内部定义的变量)的一个集合。

2. 使用std::function作为函数入参

2.1 基于传值的方式传递参数

参看下面一段代码,实现了一个注册回调函数的机制,

#include <fonctional>
void registerCallBack(std::function<void()>);

入参std::function<void()>是一个模板类对象,它可以用一个函数签名为void()的可调用对象来进行初始化;上述实现里面是一个传值调用。我们来看一下它的调用过程,

// 方法(A)
registerCallBack([=]{
    ....  // 回调函数的实现部分
})

这里使用了lambda表达式作为函数的入参,正如前面所说的lambda表达式会生成一个匿名的闭包(closure),基于这个闭包构造了一个std::function<void()>的对象,然后通过传值调用的方式把这个对象传递registerCallBack函数中使用。

3.常规使用(回调)

void fun1()
{
    std::cout << "this is fun1" << endl;
}

int fun2(int a)
{
    std::cout << "this is fun2" << endl;
    return 0;
}

std::vector<int>& fun3(int a)
{
    vector<int> data;
    std::cout << "this is fun3" << endl;
    return data;
}
std::function<void()> FUN1 = fun1;
FUN1();

std::function<int(int)> FUN2 = fun2;
FUN2(1);

std::function<std::vector<int>(int)> FUN3 = fun3;
FUN3(2);

输出如下
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路过的小熊~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值