一文看懂std::function和std::bind用法 独家原创

目录

一、c++可调用对象--std::function

二、std::bind--通用的函数适配器

三、实际举例


一、c++可调用对象--std::function

  1. 函数 函数又包含普通函数、类的静态与非静态成员函数。
  2. 函数指针
  3. 仿函数
  4. lambda表达式
  5. bind对象 其实是绑定前四种。

而上面5类对象,有一个统一的方式保存,那就是转换为std::function对象,实现类型消除机制。以前是用函数指针。

std::function就是一个对象包装器、类模板,取代函数指针:

# include <functional>
std::function<函数类型>

场景:实现函数回调。因为它可以延迟函数执行,特别适用作为回调函数。

二、std::bind--通用的函数适配器

std::bind接收一个可调用对象,生成一个新的可调用对象。

作用:

  1. 将可调用对象和其参数绑定成一个仿函数
  2. 设置默认参数,减少入参

一般形式:

auto newCallable = bind(callable, arg_list);

对于类成员函数bind需要传入对象地址,因为对象的成员函数需要this指针。函数参数std::placeholders(占位符)表示,默认参数直接写值。

场景:在绑定类非静态成员函数时特别有用。当然,你也可以用C语言指针的方式实现(作为一个C++程序员,你好意思么,嘿嘿)。或者其他可调用对象你想减少入参会使用bind。

三、实际举例

看代码:

#include <iostream>
#include <functional>

using namespace std;

// 声明一个模板
typedef std::function<int(int, int)> Functional;

// 普通函数
int AliFunc(int a, int b)
{
    return a;
}

// 类的成员函数和类的静态成员函数
class AliTest {
public:
    int Func(int a, int b)
    {
        return a;
    }
    static int SFunc(int a, int b)
    {
        return a;
    }
};

// lambda表达式
auto lambda = [](int a, int b) -> int { return a; };

// functor仿函数(也叫函数对象)
class Functor {
public:
    int operator()(int a, int b)
    {
        return a;
    }
};

int main()
{
    // 封装普通函数
    Functional obj = AliFunc;
    int res = obj(0, 0);
    cout << "normal function : " << res << endl;

    // 封装类的成员函数和static成员函数
    AliTest t;
    auto obj2 = std::bind(&AliTest::Func, &t, placeholders::_1, 666);
    res = obj2(1);
    cout << "member function : " << res << endl;
    obj = AliTest::SFunc;
    res = obj(2, 2);
    cout << "static member function : " << res << endl;

    // 封装lambda表达式
    obj = lambda;
    res = obj(3, 3);
    cout << "lambda expression : " << res << endl;

    // 封装仿函数
    Functor functorObj;
    obj = functorObj;
    res = obj(4, 4);
    cout << "functor : " << res << endl;

    return 0;
}

输出结果:

normal function : 0
member function : 1
static member function : 2
lambda expression : 3
functor : 4

可见,std::function可以封装任何可调用对象,直接赋值即可。

另外,std::bind可以绑定任何可调用对象,类成员函数需要传入类对象地址。这里没举例别的,没必要都一样,绑定其他可调用对象只是少了类对象地址这个参数。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值