C++ std::bind

转载:链接:https://www.jianshu.com/p/82407fb43475

C++ std::bind
概述
bind函数可以看作一个通用的函数适配器,所谓适配器,即使某种事物的行为类似于另外一种事物的一种机制,如容器适配器:stack(栈)、queue(队列)、priority_queue(优先级队列)。
bind函数接受一个可调用对象,生成一个新的可调用对象来适配原对象。

函数原型

  bind (Fn&& fn, Args&&... args)

bind函数接受一个逗号分割的参数列表args,对应给定函数对象fn的参数,返回一个新的函数对象。
参数列表args中:

如果绑定到一个值,则调用返回的函数对象将始终使用该值作为参数
如果是一个形如_n的占位符,则调用返回的函数对象会转发传递给调用的参数(该参数的顺序号由占位符指定)
使用

#include <functional> //bind函数 placeholders命名空间

int Plus(int x, int y) {
    return x + y;
}

int PlusOne(int x) {
    auto func = std::bind(Plus, std::placeholders::_1, 1);
    return func(x);
}

int main()
{
    std::cout << PlusOne(9) << std::endl; //结果 10
    return 0;
}

注:示例代码中的_1即为形如_n的占位符,其定义在命名空间placeholders中,而此命名空间又定义在命名空间std中

使用场景
根据bind函数的特征,有以下几个场景时可以使用bind:

当bind函数的参数列表绑定到一个值时,则调用返回的函数对象将始终使用该值作为参数。所以bind函数可以将一个函数的参数特例化,如上文的示例代码
当bind函数的参数列表是一个占位符时,调用返回的函数对象的参数顺序号由占位符指定,所以bind函数可以对调用函数对象的参数重新安排顺序,例如:

using namespace std;

void output(int a, int b, int c) {
    cout << a << " " << b << " " << c;
}

int main()
{
    auto func = bind(output, placeholders::_2, placeholders::_1, placeholders::_3);
    func(1, 2, 3); //结果 2 1 3
    return 0;
}

与std::function配合,实现回调函数。具体见文章C++ std::function,这里不再赘述。
进一步讨论
bind函数中非占位符的参数,将会以值拷贝的方式传递给返回的可调用对象中,所以直接使用bind,无法将参数以引用方式传递,或是绑定的参数类型无法拷贝。
我们需要使用ref函数(函数ref返回一个对象,包含给定的引用,此对象是可以拷贝的)来实现以引用方式传递参数,或将无法拷贝的参数类型可拷贝。
示例:

void add(int &x, int &y) {
    x++;
    y++;
}

int main()
{
    int x = 1, y = 1;
    auto func = bind(add, ref(x), y); //x以引用方式传递,y以值方式传递
    func();
    cout << x << " " << y; //结果 2 1
    return 0;
}

相似的,cref函数,用于生成一个保存const引用的类。函数ref与cref也定义在头文件functional中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值