设为首页 加入收藏

TOP

用BOOST BIND库提高C++性能(一)
2014-04-06 17:35:17 来源: 作者: 【 】 浏览:338
Tags:BOOST  BIND 提高 性能

  Boost.Bind为函数和函数对象,值语义和指针提供语义了一致的语法。我们首先通过一些简单的例子来看看它的基本用法,之后我们会延伸到嵌套绑定以实现功能组合。理解bind用法的一个关键是理解占位符(placeholder)的概念。占位符表示该参数将在函数对象里面提供。Boost.Bind提供多达9个这样的参数--_1, _2, _3, _4, _5,_6,_7,_8, _9.你可以在想要加入参数的地方使用它们。在第一个示例程序中,我们定义一个函数"nine_arguments",之后用bind表达式调用它。

  #include <IOSTREAM>

  #include boost/bind.hpp

  void nine_arguments(

  int i1,int i2,int i3,int i4,

  int i5,int i6,int i7,int i8, int i9) {

  std::cout 《 i1 《 i2 《 i3 《 i4 《 i5

  《 i6 《 i7 《 i8 《 i9 《 '

  ';

  }

  int main() {

  int i1=1,i2=2,i3=3,i4=4,i5=5,i6=6,i7=7,i8=8,i9=9;

  (boost::bind(&nine_arguments,_9,_2,_1,_6,_3,_8,_4,_5,_7))

  (i1,i2,i3,i4,i5,i6,i7,i8,i9);

  }</IOSTREAM>

  在这个程序中,你可以创建临时的匿名绑定器并且立即传参调用。如你所见,占位符的顺序是在本例中是混乱的,这使得参数的顺序也被打乱。另外,占位符可以在表达式中重复使用。示例程序1的输出是:

  921638457

  占位符的序数与参数的位置是对应的,也就是说,_1被换为第一个参数,_2被换为第二个参数,以此类推。

  #include <IOSTREAM>

  #include <BOOST bind.hpp="">

  void PlaceholderTest(int a, int b, int c)

  {

  std::cout 《 a 《 b 《 c 《 std::endl;

  }

  int main()

  {

  int a = 1, b = 2, c = 3;

  //(boost::bind(&PlaceholderTest, _1, _2))(a, b);    //error

  //(boost::bind(&PlaceholderTest, _1, _2, _1, _3))(a, b, c); //error

  //(boost::bind(&PlaceholderTest, _1, _2, _3))(a, b);    //error

  (boost::bind(&PlaceholderTest, _1, _2, _1))(a, b);  //OK,output:121

  (boost::bind(&PlaceholderTest, 99, _2, _1))(a, b)   //OK,output:9921

  } </BOOST></IOSTREAM>

  总结:

  1、参数占位符数量与函数形参数量必须一致

  2、占位符的替代值可以少于占位符数量

  3、占位符和实参可以混合使用

  翻译:调用成员函数(1)

  我们看看如何使用bind调用类的成员函数。首先我们也从一个可以由标准库完成的操作开始,这样方便我们对比标准库调用和Boost.Bind调用。当我们在标准库容器类类型中存储元素时,通常需要对部分或所有元素调用成员函数。通常的实现方法是,将这些操作可以放在一个循环中。但是现在有更好的解决办法。观察如下的简单类--status.我们之后将用它来展示Boost.Bind的简单易用和强大之处。

  class status {

  std::string name_;

  bool ok_;

  public:

  status(const std::string& name):name_(name),ok_(true) {}

  void break_it() {

  ok_=false;

  }

  bool is_broken() const {

  return ok_;

  }

  void report() const {

  std::cout 《 name_ 《  is  《

  (ok_ working nominally:terribly broken) 《 '

  ';

  }

  };

  如果我们将这个类的实例储存在vector中,当我们需要调用成员函数report时,大概要遵循以下步骤

  std::vector<STATUS> statuses;

  statuses.push_back(status(status 1));

  statuses.push_back(status(status 2));

  statuses.push_back(status(status 3));

  statuses.push_back(status(status 4));

  statuses .break_it();

  statuses .break_it();

  for (std::vector<STATUS>::iterator it=statuses.begin();

  it!=statuses.end();++it) {

  it->report();

  }</STATUS></STATUS>

  for循环能够正确完成操作,但是它冗长、低效(每次都要检查statuses.end()),还不如使用标准库中专为这种操作设计的for_each算法来的清楚。为了使用for_each替代for循环,我们需要为vector元素调用成员函数report配置一个适配器。在这个实例中,由于元素是值存储的,我们需要的是mem_fun_ref适配器:

  std::for_each(

  statuses.begin(),

  statuses.end(),

  std::mem_fun_ref(&status::report));

  这是一种更好的办法--它是如此简洁,不会对代码的作用产生任何迷惑和误解。Boost.Bind中的等效代码如下:

  std::for_each(

  statuses.begin(),

  statuses.end(),

  boost::bind(&status::report,_1));

  bind版本仍然清晰明了。这是我们第一次真正使用上面提及的Bind库占位符,它向编译器和代码阅读者传递了这样一个信息,_1将在调用绑定器的函数中被实参替换。尽管这段代码长度减少了,但在本例中,它与使用标准库mem_fun_ref几乎没有差别。

  #include <IOSTREAM>

  #include <STRING>

  #include <VECTOR>

  #include

  #include <BOOST bind.hpp="">

  class Status

  {

     

首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++ 指针的偏移 下一篇数据结构内存管理c++实现

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C语言指针从入门到基 (2025-12-26 05:21:36)
·【C语言指针初阶】C (2025-12-26 05:21:33)
·C语言指针的定义和使 (2025-12-26 05:21:31)
·在 Redis 中如何查看 (2025-12-26 03:19:03)
·Redis在实际应用中, (2025-12-26 03:19:01)