boost bind 用法

boost::bind()用来将一个函数或函数对象绑定某些参数,返回值是一个函数对象。

它提供一个任意的函数对象(仿函数)、函数、函数指针、成员函数指针。

上代码:

#include <boost/bind.hpp> 
#include <iostream> 
#include <vector> 
#include <algorithm> 

void add(int i, int j) 
{ 
  std::cout << i + j << std::endl; 
} 

int main() 
{ 
  std::vector<int> v; 
  v.push_back(1); 
  v.push_back(3); 
  v.push_back(2); 

  std::for_each(v.begin(), v.end(), boost::bind(add, 10, _1)); 
}
上述代码中bind绑定了一个一元函数对象。

    add() 函数要求两个参数,两个参数都必须传递给boost::bind()。 第一个参数是常数值10,而第二个参数则是一个怪异的 _1

_1 被称为占位符(placeholder),定义于 Boost.Bind。 除了 _1,Boost.Bind 还定义了_2_3对于 _1, boost::bind() 返回一个一元函数,即有且只有一个参数。

    当这个程序执行时,std::for_each() 对容器 v 中的每一个元素调用该一元函数。 元素的值通过占位符_1 传入到一元函数中。 这个占位符和常数值被进一步传递到 add() 函数。 通过使用这种机制,std::for_each() 只看到了由boost::bind() 所定义的一元函数。 而 boost::bind() 本身则只是调用了另一个函数,并将常数值或占位符作为参数传入给它。有点罗嗦。

    上述代码有点别扭,对每个元素加10,为什么不是两个参数呢?因为std::for_each() 要求一个一元函数作为其第三个参数。

下面看bind的二元函数用法:

#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>

bool compare(int i, int j)
{
  return i > j;
}

int main()
{
  std::vector<int> v{1, 3, 2};
  std::sort(v.begin(), v.end(), boost::bind(compare, _1, _2));
  for (int i : v)
    std::cout << i << '\n';
}
    std::sort() 算法以容器 v 的两个元素来调用该函数,并根据返回值来对容器进行排序。 如果compare()为true则swap(),容器将被按降序排列。但是,由于 compare() 本身就是一个二元函数,所以使用 boost::bind() 确是多余的。可以直接这么写:

    std::sort(v.begin(), v.end(), compare);
不过用bind可以方便的反向排序:

std::sort(v.begin(), v.end(), boost::bind(compare, _2, _1));
只改变占位符的位置。但是这种先2后1的传参方式还是不用为好。


那么问题来了,看下面的代码—— boost::bind是怎么区分类成员函数和全局函数的?

class ClassA {
public:
         void test(int, int){}
}
  
void mytest(ClassA* pObj, int, int) {}
  
typedef boost::function<void (int, int)> func;
func f1 = boost::bind(ClassA::test, this, _1, _2);
func f2 = boost::bind(mytest, pObj, _1, _2); 

关于bind的内部原理,
下面的示例程序说明了一切:

#include <stdio.h>
  
template<typename... ARGS>
void bind(void (*func)(ARGS...), ARGS... args)
{
   printf("plain function\n");
   func(args...); // std::forward<> 从略。
}
  
template<typename CLASS, typename... ARGS>
void bind(void (CLASS::*func)(ARGS...), CLASS* clz, ARGS... args)
{
   printf("member function\n");
   (clz->*func)(args...);
}
  
template<typename CLASS, typename... ARGS>
void bind(void (CLASS::*func)(ARGS...) const, const CLASS* clz, ARGS... args)
{
   printf("const member function\n");
   (clz->*func)(args...);
}
  
void foo(int arg)
{
   printf("foo %d\n", arg);
}
  
class Bar
{
  public:
   void write(double arg)
   {
     printf("Bar::write %f\n", arg);
   }
  
   void read(long arg) const
   {
     printf("Bar::read %ld\n", arg);
   }
};
  
void zoo(Bar* x)
{
   printf("zoo %p\n", x);
}
  
int main()
{
   bind(foo, 123);
   Bar bar;
   bind(&Bar::write, &bar, 3.14);
   bind(&Bar::read, &bar, 42L);
   bind(zoo, &bar);
} 

这是 Partial Template Specialization技术,即模板的"偏特化"或叫"部分特化"。










  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值