zoukankan      html  css  js  c++  java
  • 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.         //使用绑定器来调用类成员函数  
    17.         std::cout << "First:"<<std::endl;  
    18.         std::for_each(vRect.begin(), vRect.end(),   
    19.             boost::bind(&CObjBind::Fun, this, _1, 1, 2));  
    20.   
    21.         std::cout << "Second:"<<std::endl;;  
    22.         std::for_each(vRect.begin(), vRect.end(),   
    23.             boost::bind(&CObjBind::Fun, this, 1, _1, 2));  
    24.   
    25.     }  
    26. private:  
    27.     void Fun(int x, int y, int z)  
    28.     {  
    29.         std::cout << "CObjBind::Fun:" << x << "," << y << "," << z << std::endl;  
    30.     }  
    31.   
    32. };  

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

    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库里不可缺少的一部份了,比如算法、线程、网络等库中,都需要使用绑定器进行适配,以便达到高效、简洁、方便等目的。

  • 相关阅读:
    Atom实例
    订阅基础:RSS、ATOM、FEED、聚合、供稿、合烧与订阅
    XML模式:Dublin Core
    Dublin Core
    海量数据的理想存储方案
    百亿级别数据量,又需要秒级响应的案例,需要什么系统支持呢?下面介绍下大数据实时分析工具Yonghong Z-Suite
    用HiveDB横向切分MySQL数据库
    超详细单机版搭建hadoop环境图文解析
    从String.valueOf(null)说起
    js闭包理解
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4060867.html
Copyright © 2011-2022 走看看