C++中泛型算法详解4:使用参数绑定(bind)实现的可调用对象

前言

为什么要引入bind函数?

对于那种只在一两个地方使用的简单操作,使用lambda是最有用的

如果我们需要在很多地方使用相同的操作,通常应该定义一个函数,而不是编写多个相同的lambda表达式。

如果lamnda函数的捕获列表为空,通常我们可以使用函数代替。

但是对于捕获局部变量的lambda,就需要bind函数来帮忙。

所以bind函数的应用场景,通常和传入谓词有关的STL泛型算法相关联。

参数绑定

通俗的说,bind函数就是将原本的函数做了一层包装,然后露出来新的参数列表来与外界交互。

  • 头文件functional
  • 可以当做一个通用的函数适配器(类比容器适配器的概念)
  • 接收可调用对象,生成新的可调用对象来配合源对象的参数列表

bind的一般形式:

auto newCallable = bind(callable, arg_list);

  • newCallable : 可调用对象
  • arg_list:参数列表,对应callable的参数

当我们调用newCallable的时候,newCallable会调用Callable,并传递给他arg_list

bind的参数

arg_list中的参数,包含形为_n的参数名字。这些参数是占位符,表示传递给newCallable的参数位置。

数字n表示生成的可调用对象中参数的位置: _1为newCallable的第一个参数,以此类推。

名字_n都定义在名为placeholders的命名空间。所以在使用的时候需要在前面加入这么一行:
using namespace std::placeholders;

关于占位符和原本函数参数顺序的深究:

参数列表中的_n: 表示为传递给newCallable的参数个数与对应位置(按照n值的顺序)

参数列表本身参数的顺序,表示callable传入的参数

举个例子:

auto g = bind(f, a, b, _2, c, _1);

其中callable函数f有五个参数,分别按照{a, b, _2, c, _1}的顺序传入

bind后的NewCallable函数,有两个参数,分别是{_1, _2},对应f中的第五个和第三个参数。

当我们调用g的时候,第一个参数实际被传到f的最后一个参数。

绑定引用参数

因为除了占位符外其他的参数,bind函数都是按照拷贝的方式返回到bind的可调用对象中。

但是,有时候我们希望引用方式传递参数,或者,有些参数类型无法使用拷贝,比如iostream

实现方法

使用标准库ref函数

  • 定义在头文件functional中
  • 函数ref返回一个对象,包含给定的引用。

举个例子:

// bind的源函数
ostream &print(ostream &os, const string &s, char c){
    return os << s << c;
}

// 使用os的引用
for_each(words.begin(), words.end(), bind(print, ref(os), _1, ' '));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值