bind是这样一种机制,它可以预先把指定可调用实体的某些参数绑定到已有的变量,产生一个新的可调用实体,这种机制在回调函数的使用过程中也颇为有用。C++98中,有两个函数bind1st和bind2nd,它们分别可以用来绑定functor的第一个和第二个参数,它们都是只可以绑定一个参数。各种限制,使得bind1st和bind2nd的可用性大大降低。C++0x中,提供了std::bind,它绑定的参数的个数不受限制,绑定的具体哪些参数也不受限制,由用户指定,这个bind才是真正意义上的绑定,有了它,bind1st和bind2nd就没啥用武之地了,因此C++0x中不推荐使用bind1st和bind2nd了,都是deprecated了。

bind1st

这个函数相当我们可以绑定第一个值,可以将一个二元操作转换为一元操作。

void bind_test() {auto is_large_ten = std::bind1st(std::less<int>(), 10);std::cout << is_large_ten(5) << std::endl;std::cout << is_large_ten(15) << std::endl;
}int main() {bind_test();return 0;
}

如果我们需要判断一个数是否小于10,那么因为10是固定的,相当只要传入一个变量即可,因此这里使用函数适配器将std::less适配成为is_large_ten.

其实这个函数是非常简单的,返回一个对象给调用者,这个对象有如下特性:

  1. 保存被适配的函数。
  2. 保存被适配函数的第一个参数的值。
  3. 实现调用操作result_type operator()(const argument_type& _Right).
  4. 在调用操作中调用被适配函数,第一个参数为绑定的值,第二个参数为传递的参数。

bind

bind是一个函数的适配器,可以将一个函数的参数特例化

绑定普通函数

int fun(int a, int b, int c, int d) {std::cout << a << std::endl;std::cout << b << std::endl;std::cout << c << std::endl;std::cout << d << std::endl;return 0;
}void bind_test() {auto f = std::bind(fun, std::placeholders::_1, std::placeholders::_2, 300, 400);f(100, 200);
}int main() {bind_test();return 0;
}

其中std::placeholders::_1是一个占位符号。接下来我们看下std::bind的具体实现原理。

绑定成员函数

#include <functional>class A
{
public:int Func(int x, int y);
};int main() {A a;auto bf2 = std::bind(&A::Func, a, std::placeholders::_1, std::placeholders::_2);bf2(10, 20); ///< same as a.Func(10, 20)std::function< int(int)> bf3 = std::bind(&A::Func, a, std::placeholders::_1, 100);bf3(10); ///< same as a.Func(10, 100)return 0;
}

上面的例子中,bf1是把一个两个参数普通函数的第一个参数绑定为10,生成了一个新的一个参数的可调用实体体; bf2是把一个类成员函数绑定了类对象,生成了一个像普通函数一样的新的可调用实体; bf3是把类成员函数绑定了类对象和第二个参数,生成了一个新的std::function对象。看懂了上面的例子,下面我们来说说使用bind需要注意的一些事项:

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

参考文献

  • https://blog.csdn.net/ljlinjiu/article/details/81777633?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
  • https://blog.csdn.net/xiangbaohui/article/details/106755685?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-7&spm=1001.2101.3001.4242

std::bind介绍相关推荐

  1. C++11 - std::bind简要介绍以及可绑定函数的几种形式总结

    文章目录 1 std::bind 1.1 函数模板说明 1.2 函数模板参数说明 1.3 函数模板返回值说明 2 std::bind可绑定的几种函数形式总结 2.1 绑定普通函数或者静态函数 2.1. ...

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

    std::bind函数是用来绑定函数调用的某些参数的.std::bind它可以预先把指定可调用实体的某些参数绑定到已有的变量,产生一个新的可调用实体.它绑定的参数的个数不受限制,绑定的具体哪些参数也不 ...

  3. std::bind技术内幕

    引子 最近群里比较热闹,大家都在山寨c++11的std::bind,三位童孩分别实现了自己的bind,代码分别在这里: 木头云的实现 mr.li的实现 null的实现,null的另一个版本的实现 这些 ...

  4. boost::bind 介绍

    boost::bind 介绍 这篇文章介绍boost::bind()的用法, 文章的主要内容是参考boost的文档. 1. 目的 boost::bind 是std::bindlist 和 std::b ...

  5. C++11 std::function, std::bind, std::ref, std::cref

    C++11 std::function, std::bind, std::ref, std::cref 转自:http://www.jellythink.com/ std::function 看看这段 ...

  6. 函数对象,lamdda表达式,function函数包装,std::bind函数绑定

    一 函数对象 在学习其他知识之前,先来学习函数对象,然后引出std::lambda.std::function.std::bind等内容的学习,那么究竟什么是函数对象呢? 函数对象(Function ...

  7. 【C++】C++11的std::function和std::bind用法详解

    在设计回调函数的时候,无可避免地会接触到可回调对象.在C++11中,提供了std::function和std::bind两个方法来对可回调对象进行统一和封装. 可调用对象 C++中有如下几种可调用对象 ...

  8. C++11新特性之std::function std::bind

    std::function 在c++98&03时我们通常使用回调函数来处理一些需要某种场景下才触发的回调操作,但回调函数有一个限制就是它只能赋值给同类型的全局或者静态函数,对于其他有相同的返回 ...

  9. C++——包装器std::function与绑定器std::bind

    C++--包装器std::function与绑定器std::bind 1.可调用对象的包装器 std::function是可调用对象的包装器.它是一个类模板,可以容纳除了类成员(函数)指针之外的所有可 ...

最新文章

  1. greendao3出现 Error:Execution failed for task ':app:greendao'
  2. Netty ObjectPool对象池技术原理分析
  3. WordPress打开速度很慢的解决方法
  4. 面试必会系列 - 2.1 MySQL知识点大汇总(基本架构,存储引擎,锁,事务,索引,B+树等等)
  5. java集合体检套餐管理系统_体检套餐管理系统
  6. 巴黎市中心降下2019年第一场雪
  7. python机器学习-乳腺癌细胞挖掘
  8. Ubuntu修改hosts文件
  9. php编程三阶魔方,三阶魔方还原教程
  10. 互联网发展的四个阶段
  11. [Netlist29-358] Reg ‘Counter[7]‘ of type ‘FDCPE’ cannot be timed accurately. Hardwarebehavior may be
  12. 使用Kinect2作为Oculus游戏应用的输入设备
  13. 家用千兆路由器排行榜前十名_家用路由器排名前十名
  14. Android Animation动画详解(二): 组合动画特效
  15. 多角度解读新兴公链Sui:团队、架构、代币、生态等
  16. RZ,NRZ,NRZI
  17. SQL获取当前时间(日期)
  18. google 浏览器钉钉日志异常
  19. 证明:任何一个正整数均可以表示为两个互质整数的和
  20. SQL注入——基于时间的盲注(sqli-labs less9)

热门文章

  1. JS将EXCEL文件导入前端第一行未出现或者出现F1F2F3的解决方法……
  2. WinAPI: 输入光标相关的函数[3]
  3. CTO(首席技术官)
  4. 写了个Python脚本监控nginx进程
  5. Dynamics AX 2009 升级PreSynchnoize时的无反应的解决
  6. cisco PIX防火墙的配置及注解完全手册
  7. 打开浏览器的包 node_如何发布可在浏览器和Node中使用的软件包
  8. 车联网APP,安全设施薄弱的山寨品
  9. cmd库的导入Java,在cmd命令窗口导入第三方jar包来运行java文件
  10. java 匿名list,java创造匿名对象的两种方法