C++11中的std::bind

导言
bind是这样一种机制,它可以将参数绑定于可调用对象,产生一个新的可调用实体,这种机制在函数回调时颇为有用。C++98中,有两个函数bind1st和bind2nd,它们分别用来绑定functor的第一个和第二个参数,都只能绑定一个参数。C++98提供的这些特性已经由于C++11的到来而过时,由于各种限制,我们经常使用bind而非bind1st和bind2nd。在C++11标准库中,它们均在functional头文件中。而C++STL很大一部分由Boost库扩充,STL中的shared_ptr等智能指针,bind及function都是由Boost库引入。在写代码过程中,要养成使用bind,function,lambda和智能指针的习惯,它们非常强大简洁实用。
正文

1. 过时的bind1st和bind2nd

bind1st(op, arg) :op(arg, param)
bind2nd(op, arg) :op(param, arg)

vector<int> coll {1, 2, 3, 4, 5, 11, 22, 5, 12};
// 查找第一个元素值大于10的元素
std::find_if(coll.begin(), coll.end(), // range
             std::bind2nd(std::greater<int>(), 10));
// 查找元素值大于10的元素的个数
int _count = count_if(coll.begin(), coll.end(), // range
              std::bind1st(less<int>(), 10)/*判断准则*/);

2. C++11中的std::bind

/*function object内部调用plus<>(也就是operator+),以占位符(placeholders)_1为第一个参数,以10为第二个参数,占位符_1表示实际传入此表达式的第一实参,返回“实参+10”的结果值*/
auto plus10 = std::bind(std::plus<int> (), std::placeholders::_1, 10);
std::cout << plus10(7) << std::endl;// 17

// (x + 10)*2,下面的代码中x=7
std::bind(std::multiplies<int>(), 
          std::bind(std::plus<int>(), std::placeholders::_1, 10),// i+10
          2)(7);

注意:上面所用的less<int>(), greater<int>()以及plus<int>()等都是C++预定义的Function Object。因此我们可以知道,bind可以把参数绑定到“函数对象”上。除此之外,bind()还可以把参数绑定到普通函数、类成员函数、甚至数据成员等。

3. 使用std::bind要注意的地方

  • bind预先绑定的参数需要传具体的变量或值进去,对于预先绑定的参数,是pass-by-value的;
  • 对于不事先绑定的参数,需要传std::placeholders进去,从_1开始,依次递增。placeholder是pass-by-reference的;
  • bind的返回值是可调用实体,可以直接赋给std::function对象;
    对于绑定的指针、引用类型的参数,使用者需要保证在可调用实体调用之前,这些参数是可用的;
  • 类的this可以通过对象或者指针来绑定

4. 何时使用std::bind

  • 你需要绑定一个调用到一个普通函数,使用部分或全部参数
  • 你需要绑定一个调用到一个成员函数,使用部分或全部参数
  • 你需要嵌套组合函数对象(比如x>5&&x<10, (i+10)*2)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值