zoukankan      html  css  js  c++  java
  • boost::bind的使用方法

    bind - boost

    头文件: boost/bind.hpp

    bind 是一组重载的函数模板.
    用来向一个函数(或函数对象)绑定某些参数. 
    bind的返回值是一个函数对象.

    它的源文件太长了. 看不下去. 这里只记下它的用法:

    9.1 对于普通函数

    假如有函数 fun() 如下: 
     void fun(int x, int y) {
      cout << x << ", " << y << endl;
     }
    现在我们看看怎么用 bind 向其绑定参数. 
    对于像 fun 这样的普通函数. 若fun 有n个参数. 则 bind 需要 n+1 个参数: 原始函数的地址 以及 n个要绑定的参数.

    第 1种用法: 
    向原始函数 fun 绑定所有的参数
     boost::bind(&fun, 3, 4)     // bind的实参表依次为: 要绑定的函数的地址, 绑定到fun的第一个参数值, 第二个参数值...
            // fun有多少个参数, 这里就要提供多少个.
    表示将 3 和 4 作为参数绑定到 fun 函数. 
    因为绑定了所有的参数. 现在我们调用bind所返回的函数对象:
     boost::bind(&fun, 3, 4)( );  //无参数. 
    就会输出 3, 4

    第 2种用法: 
    向原始函数 fun 绑定一部分参数
     boost::bind(&fun, 3, _1)    // bind的实参表依次还是: 要绑定的函数的地址, 要绑定到fun的第一个参数值, 然后注意
            // 因为我们不打算向fun绑定第2个参数(即我们希望在调用返回的Functor时再指定这个参数的值)
            // 所以这里使用 _1 来占位. 这里的 _1 代表该新函数对象被调用时. 实参表的第1个参数.
            // 同理下边还会用到 _2 _3 这样的占位符. 
    这里只为fun绑定了第一个参数3. 所以在调用bind返回的函数对象时. 需要:
     boost::bind(&fun, 3, _1)(4);  //这个4 会代替 _1 占位符.
    输出 3, 4
    同理 boost::bind(&fun, _1, 3)(4); 
    输出 4, 3

    第 3种用法:
    不向 fun 绑定任何参数
     boost::bind(&fun, _1, _2)   // _1 _2 都是占位符. 上边已经说过了.
    所以它就是 将新函数对象在调用时的实参表的第1个参数和第2个参数 绑定到fun函数.  
     boost::bind(&fun, _1, _2)(3, 4);    // 3将代替_1占位符, 4将代替_2占位符.
    输出 3, 4
    同理 boost::bind(&fun, _2, _1)(3, 4);   // 3将代替_1占位符, 4将代替_2占位符.
    会输出 4, 3  
    同理 boost::bind(&fun, _1, _1)(3);     // 3将代替_1占位符
    会输出 3, 3

    对于普通函数就这些. 对于函数对象. 如:
     struct Func {
      void operator()(int x) {
       cout << x << endl;
      }
     } f;
    绑定的时候可能要指出返回值的类型:
     boost::bind<void>(f, 3)();  //指出返回值的类型 void
     

    9.2 对于非静态成员函数

    假如有:
     struct A {
      void func(int x, int y) {
       cout << x << "," << y << endl;
      }
     };
     
     A a;  
     A* pa = new A; //指针
     boost::shared_ptr<A> ptr_a(pa);  //智能指针.
     
    现在要向像 A::func 这样的非静态成员函数绑定. 
    若A::func有n个参数, 则 bind 要有 n+2 个参数: 指向成员函数fun的指针, 绑定到this的对象, n个参数.
    如:  
     boost::bind(&A::func, a, 3, 4)();    //输出 3, 4
     boost::bind(&A::func, pa, 3, 4)();   //输出 3, 4
     boost::bind(&A::func, ptr_a, 3, 4)();//输出 3, 4
    同样可以用 _1 这样的占位符. 如:
     boost::bind(&A::func, _1, 3, 4)(ptr_a);//输出 3, 4

    可以看出. 不论传递给bind 的第2个参数是 对象. 对象指针. 还是智能指针. bind函数都能够正常工作.


    9.3 bind嵌套

    有个类如下. 记录人的信息:
     class Personal_info {
      string name_;
      int age_;
     public:
      int get_age();
      string name();
     };

     vector<Personal_info> vec; 
     ...
    现在要对 vec 排序. 可以用 bind 函数做一个比较谓词
     std::sort(  
      vec.begin(),  
      vec.end(),  
      boost::bind( 
       std::less<int>(),    
       boost::bind(&personal_info::age,_1),     //_1 占位符是 sort 中调用比较函数时的第一个参数.
       boost::bind(&personal_info::age,_2)));   //_2 占位符是 sort 中调用比较函数时的第二个参数.


    9.4 函数组合

    假如有:
     vector<int> ints;
     ...
    想用 std::count_if() 来求ints中有多少是 >5 且 <=10 的. 这在常规代码中通常就要写一个函数来实现这个谓词:
     if (i>5 && i<=10) ...
    现在用 bind则可以:
     std::count_if(  
      ints.begin(),  ints.end(),  
      boost::bind(    
       std::logical_and<bool>(),    
       boost::bind(std::greater<int>(),_1,5),    
       boost::bind(std::less_equal<int>(),_1,10)));

    9.5 绑定到成员变量

    有:
     map<int, string> my_map;
     my_map[0]="Boost";my_map[1]="Bind";
    现在要输出所有元素的 second 成员. 也就是输出这些字符串. 其中的打印函数如下:
     void print_string(const string& s) {  
      std::cout << s << ' ';
     }
    则可以:
     for_each(  
      my_map.begin(),  
      my_map.end(),  
      boost::bind(
       &print_string, 
       boost::bind(&std::map<int,std::string>::value_type::second,_1)
       )
      );

  • 相关阅读:
    天气预报FLEX版本
    关于“ORA01000: 超出打开游标的最大数”
    WIN7(x64) IIS7.5 404.17错误:请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理。
    解决GDI+中“内存不足”问题
    Stack Overflow Exception
    清洁的Javascript
    设置SQL Server数据库中某些表为只读的多种方法
    程序员肿么了?为何总被认为是“屌丝”
    jquery datepicker 显示12个月份
    apache2.4配置虚拟主机随记
  • 原文地址:https://www.cnblogs.com/lidabo/p/3985969.html
Copyright © 2011-2022 走看看