boost库在工作(15)绑定器与函数对象之三

前面已经可以优美地解决两个参数的函数给算法for_each调用了,但是又会遇到这样的一种情况,当需要三个参数或者三个以上的参数给算法for_each调用呢?从STL里的绑定器bind1st,显然是不行了,因为它最多只支持两个参数,那还有什么办法呢?这时就需要使用boost库里强大的绑定器bind了。它不仅适用的情况比STL库里的多,还更加方便,更加人性化。下面就来看看怎么样绑定三个参数的类成员函数的例子,如下:

[cpp] view plaincopy

  1. //调用类的成员函数,但参数两个以上。
  2. //软件开发人员: 蔡军生  2013-02-10
  3. //QQ: 9073204
  4. class CObjBind
  5. {
  6. public:
  7. void Test(void)
  8. {
  9. //
  10. std::vector< int > vRect;
  11. vRect.push_back(1);
  12. vRect.push_back(2);
  13. vRect.push_back(3);
  14. vRect.push_back(10);
  15. //使用绑定器来调用类成员函数
  16. std::cout << "First:"<<std::endl;
  17. std::for_each(vRect.begin(), vRect.end(),
  18. boost::bind(&CObjBind::Fun, this, _1, 1, 2));
  19. std::cout << "Second:"<<std::endl;;
  20. std::for_each(vRect.begin(), vRect.end(),
  21. boost::bind(&CObjBind::Fun, this, 1, _1, 2));
  22. }
  23. private:
  24. void Fun(int x, int y, int z)
  25. {
  26. std::cout << "CObjBind::Fun:" << x << "," << y << "," << z << std::endl;
  27. }
  28. };

在这个例子里看到使用绑定器的代码行,如下:

boost::bind(&CObjBind::Fun, this, _1, 1, 2)

绑定器bind的第一个参数直接使用类成员函数指针就行了,不像前面要添加mem_fun函数来转换;第二个参数是继续输入this指针;第三个参数是_1,前面带下划线的1是比较奇怪了,其实这个是bind器的占位符,用来指定生成的函数对象参数传给绑定的函数参数顺序;最后两个参数都传送给函数的参数。这样函数void Fun(int x, int y, int z)的三个参数就传送过了,大体就是这样调用Fun(_1,1,2)。因而输出的结果如下:

CObjBind::Fun:1,1,2

CObjBind::Fun:2,1,2

CObjBind::Fun:3,1,2

CObjBind::Fun:10,1,2

从输出的结果中可以看到,占位符在那里就是算法for_each传入参数的地方。相当如下的调用:

Fun(x,1,2)(x);

接着来看占位符放到第二个位置,如下这样:

std::for_each(vRect.begin(), vRect.end(),

boost::bind(&CObjBind::Fun,this, 1, _1, 2));

这里占位_1放在第二个参数位置,输出的结果如下:

CObjBind::Fun:1,1,2

CObjBind::Fun:1,2,2

CObjBind::Fun:1,3,2

CObjBind::Fun:1,10,2

跟前面的比较,算法for_each传入的值在第二个参数传入。

boost库里的绑定器bind与STL里定义的两个相比,参数比较多,可以多达9个,也许你会问,如果多于9个怎么样办呢?多于9个的情况是比较少的,就算有了,在这种情况之下,也需要定义一个数据结构来保存,传递一个指针进来比较合算,因为这样参数少,方便维护,同样传送的效率提高了。第二个优点是绑定成员函数简单,不需要调用mem_fun函数,第三个优点是提供占位符,可以随便指定到那个参数传入。9个参数的占位符的名称是_1,_2,_3,一直接到_9。

boost库里的绑定器是兼容比较好,还可以支持STL里的二元运算函数的绑定,如下:

bool bResult =bind(std::less<int>(), 5, 9)();

std::cout << bResult<< std::endl;

下面再来看一个复杂一点的例子,比如实现对值x进行这样的判断:

if (x > 10 && x <= 20)

{

}

使用绑定器就可以写成下面这样:

//实现 if ( x > 10 && x <= 20)

boost::bind(  std::logical_and<bool>(),

boost::bind(std::greater<int>(),_1, 10),

boost::bind(std::less_equal<int>(),_1, 20))(15);

通过这样的组合,就可以实现很复杂的表达式运算,这样就可以给算法提供更加复杂的条件,达到我们需要达到的目的。

如下面的例子,可以合适地删除指定条件的元素:

vRect.erase(std::remove_if(vRect.begin(), vRect.end(),

boost::bind(&CObjBind::IsLess,this, _1)), vRect.end());

在这个例子里,先调用算法remove_if来删除数组中小于指定条件的元素,并返回无效元素的起始位置,然后调用vRect.erase删除后面无效的元素,最终在数组里就剩下有效的元素了。

总之,绑定器已经成为boost库里不可缺少的一部份了,比如算法、线程、网络等库中,都需要使用绑定器进行适配,以便达到高效、简洁、方便等目的。

时间: 2024-11-05 21:05:15

boost库在工作(15)绑定器与函数对象之三的相关文章

boost库在工作(39)网络UDP异步服务端之九

前面创建的UDP服务器和客户端,都是同步的方式,也就是说当接收数据时,不能参与别的事情执行的.如果在一个只有界面线程的程序里,又不想创建多线程,导致复杂程度的增加,在这种情况之下,我们还有一个方案可以选择,就是创建一个异步的UDP服务器或客户端,这样既有单线程的简单性,也可以让客户随便操作界面的快速响应的特性.在boost库里使用io_service对象来实现异步是轻而易举的事情,因为封装的接口简单.明了.具体的代码如下: [cpp] view plaincopy // boost_028.cp

C++标准库(七)之图解bind函数对象

bind与普通函数的绑定 1. bind可以将用户提供的需要一个参数的函数转换为一个不需要参数的函数对象: 2.使用非成员函数,在使用前和使用时提供参数: bind与类的非静态成员函数的绑定 1.非静态函数成员的使用需要一个隐式的this参数 2.也可以将一个隐式的函数指针显式的传递给需要一个参数的函数对象 3.函数对象经常同时使用之前绑定参数和调用时提供参数: 参考: 1.http://blog.think-async.com/2010/04/bind-illustrated.html 2.<

共享boost::deadline_timer封装模板,可以接受任何函数对象

// // fox_timer.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2014-2015 yoen.xu (181471112 at  qq dot com) // //说明 //eg:  fox_timer<T>::run(io_, func, interval); //     T 为func的返回类型,当T为int的时候(范围值-1代表取消定时器,0定时器时间不变 >0重置定时器时间) //       可以使用cancle()来取

Linux/ubuntu下的boost库安装

我一直都没有写博客的习惯,最近正好在研究linux下的开发(目前也只是粗粗的研究),且用到了boost库,就乘此机会写点什么,最起码记录一下我在安装boost的一些步骤,主要给和我一样的linux开发新手们提供点借鉴(当然如果看到这篇文档的话 ),作者(jwybobo2007). 1.下载boost库 这个我就不说啥了,去官网看一下就能下到:www.boost.org ,现在的版本更新到了1.44 2.执行:sudo apt-get install build-essential 不为别的,就是

所有的 Boost 库文档的索引

按字母顺序列出的库 按类别列出的库 算法 破碎的编译器的解决方法 并发编程 容器 正确性和测试 数据结构 特定于域的 函数对象和高阶编程 泛型编程 图像处理 输入/输出 跨语言支持 迭代器 语言功能仿真 数学和数字 内存 解析 模式和习语 预处理器元编程 编程接口 状态机 字符串和文本处理 系统 模板元编程 杂项 图书馆从提高退休 请参阅入门页面以了解如何下载. 构建和安装库. 按字母顺序列出的库 蓄能器-增量计算和统计累加器,Eric Niebler 从集合框架 算法-有用的通用算法,从马歇尔

C++ Boost库分类总结

c# 程序员写c++,各种不适应.尤其是被内存操作和几十种字符串类型的转换,简直疯了,大小写转换竟然要手动写代码实现. Boost看介绍不错,也不知道能不能跨平台.过几天要上linux写c++, 也不知道这东西能不能用. 转自: https://blog.csdn.net/svap1/article/details/80496489 按照实现的功能,Boost可为大致归入以下20个分类,在下面的分类中,有些库同时归入几种类别.字符串和文本处理库 a) Conversion库:对C++类型转换的增

在VS2013下配置BOOST库

1.安装Boost库 (1).首先打开Boost的官网(http://www.boost.org/),找到下载位置,如下图中红框所示,此时最新的版本是1.64.0: (2).点击进入下载页面,选择你需要的文件下载,这里我选择windows下的zip文件: (3).下载好后,解压,得到文件目录如下图,找到其中的bootstrap.bat文件: (4).双击运行bootstrap.bat后,让其自动运行完成后,会发现当前文件夹中增加了几个文件,找到其中的bjam.exe,如下图所示 (5).双击运行

VS2010 编译安装boost库

实践是最好的办法..学习C++,想试试线程,然后打算用boost库,结果boost库编译差点吓到我..没看到比较完整的安装教程..一直耽搁.今天动手.完成了.方法记录如下:1.下载boost从boost官网( http://www.boost.org )上下载最新的boost版本,现在最新是1.49版本,解压到自定义目录(我解压到了D:/program files,最终的目录结构是D:\Program Files\boost_1_49_0) 2.编译安装 在D:\Program Files\bo

2015-03-12---外观模式,建造者模式(附代码),观察者模式(附代码),boost库应用

今天白天主要看了boost库的应用,主要是经常使用的一些库,array,bind,function,regex,thread,unordered,ref,smartpointers库,晚上看了看设计模式.主要就是外观模式.建造者模式和观察者模式.我们从boost简要说起. 事实上boost的库好多东西在c++11里面已经有了.比方bind,仅仅只是boost的库的bind比c++11用着感觉要方便.事实上有些东西我自己由于也没实用c++做过什么大的项目.所以不敢乱说,仅仅敢说点建议性的,关于bi