C++11 std::function和std::bind绑定器

前言

C++11增加了std::function和std::bind,使得使用标准库函数时变得方便,而且还能方便地实现延迟求值。C++中,存在“可调用对象”这么一个概念。准确来说,可调用对象有如下的定义:

(1)是一个函数指针

(2)是一个具有operator()成员函数的类对象(仿函数)

(3)是一个可被转换为函数指针的类对象

(4)是一个类成员(函数)指针

1. std::function

std::function是可调用对象的包装器。它是一个类模板,可以容乃除了类成员(函数)指针之外的所有可调用对象。通过制定它的模板参数,他可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟执行他们。

1.1 std::function的基本用法

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <functional>   //std::function

using std::cout;
using std::endl;

void func(int a, int b)     //普通函数
{
    cout << __FUNCTION__ << "(" << (a+b) << ")" << endl;
}

class A
{
public:
    static int class_func(int x)  //静态成员函数
    {
        cout << __FUNCTION__ << "(" << x << ")" << endl;
        return x;
    }
};

class B
{
public:
    int operator()(int x)   //仿函数
    {
        cout << __FUNCTION__ << "(" << x << ")" << endl;
        return x;
    }
};

int main()
{
    //普通函数
    std::function<void(int, int)> func1 = func;
    func1(1000, 24);

    //类的静态成员函数
    std::function<int(int)> func2 = A::class_func;
    cout << func2(2048) << endl;

    //仿函数
    B m_b;
    std::function<int(int)> func3 = m_b;
    cout << func3(4096) << endl;

    return 0;
}

当给定std::function填入合适的函数名之后,它就变成了可以容乃所有这一类调用方式的“函数包装器”。

1.2 std::function作为回调函数

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <functional>   //std::function

using std::cout;
using std::endl;

class A
{
public:
    A(const std::function<int(int)>& func):f_callback(func)
    {}
private:
    std::function<int(int)> f_callback;

public:
    void notify(int num)  //静态成员函数
    {
        cout << __FUNCTION__ << "(" << f_callback(num) << ")" << endl;
    }
};

class B
{
public:
    int operator()(int x)   //仿函数
    {
        cout << __FUNCTION__ << "(" << x*2 << ")" << endl;
        return x;
    }
};

int main()
{
    //仿函数
    B m_b;
    A m_a(m_b);
    m_a.notify(1024);

    return 0;
}

在上面的例子中std::function可以取代函数指针的作用。因为它可以保存函数延迟执行,所以比较适合作为回调函数,也可以把它看做类似于C#中特殊的托管。

1.3 std::function作为函数参数

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <functional>   //std::function

using std::cout;
using std::endl;

void func(int a, int b)     //普通函数
{
    cout << __FUNCTION__ << "(" << (a+b) << ")" << endl;
}

void call_func(int x, int y, std::function<void(int, int)>& f)
{
    f(x, y);
}

int main()
{
    std::function<void(int, int)> func1 = func;
    call_func(1024, 96, func1);

    return 0;
}

2. std::bind绑定器

std::bind用来将可调用对象与其参数进行绑定。绑定之后的结果可以使用std::function进行保存,并延迟调用到任何需要的时候。一般来讲,它主要有两大作用:

(1)将可调用对象与其参数一起绑定成为一个仿函数

(2)将多元可调用对象转换成为1元或是(n-1)元调用对象,既只是绑定部分参数

2.1 std::bind基本用法

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <functional>   //std::function

using std::cout;
using std::endl;

void func(int a, int b)     //普通函数
{
    cout << __FUNCTION__ << "(" << (a+b) << ")" << endl;
}

void call_func(int x, int y, const std::function<void(int, int)>& f)
{
    f(x, y);
}

int main()
{
    auto func2 = std::bind(func, std::placeholders::_1, std::placeholders::_2);
    call_func(1024, 96, func2);

    return 0;
}
实际上std::bind的返回类型是一个stl内部定义的仿函数类型,在这里就只需要知道它是一个仿函数,可以赋值给一个std::function,这里直接用std::function类型来保存std::bind的返回值也是可以的。

其中std::placeholders::_1是一个占位符,代表这个文职将在函数调用时,被传入的第一个参数代替。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值