使用BOOST BIND库提高C++程序性能(二)

2014-11-24 11:28:56 · 作者: · 浏览: 1
码的语法已经有所改变,尽管我们要做的工作几乎相同。当然,如果代码的语法和上面的例子一样就最好了,这样我们就可以更多地关注代码到底做了些什么而不是它怎么做的。使用Bind,我们不需要显式指明要处理的元素是指针(这在容器类型中已经说明了,重复的信息在现代的库里面显然是不必要的)

std::for_each(
	p_statuses.begin(),
	p_statuses.end(),
	boost::bind(&status::report,_1));

如你所见,这与之前非指针元素的代码没有任何区别。也就是说如果你理解了刚才的bind,那么这个也能理解。

原创:编程实验

#include 
    
     
#include 
     
       #include 
      
        #include 
       
         #include 
        
          class Status { public: Status(const std::string &name) : name_(name), ok_(true){} void BreakIt() { ok_ = false; } bool IsBroken() const { return ok_; } void Report() const { std::cout << name_ << is << (ok_   ok : broken) << std::endl; } private: std::string name_; bool ok_; }; int main() { std::vector
         
           v_pstatus; v_pstatus.push_back(new Status(status 1)); v_pstatus.push_back(new Status(status 2)); v_pstatus.push_back(new Status(status 3)); v_pstatus.push_back(new Status(status 4)); v_pstatus[1]->BreakIt(); v_pstatus[2]->BreakIt(); std::cout << use or: << std::endl; for (std::vector
          
           ::iterator it = v_pstatus.begin(); it < v_pstatus.end(); it++) { (*it)->Report(); } std::cout << use or_each, mem_fun_ref: << std::endl; std::for_each(v_pstatus.begin(), v_pstatus.end(), std::mem_fun(&Status::Report)); std::cout << use or_each, bind: << std::endl; std::for_each(v_pstatus.begin(), v_pstatus.end(), boost::bind(&Status::Report, _1)); }
          
         
        
       
      
     
    

总结:

只有bind保持了形式不变

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

我们决定使用指针后,有另外一个问题,即指针的生命周期控制。我们必须手动释放p_statuses中的元素,这很容易出错而且没有必要。因此,我们可能选择使用智能指针(smart pointers),代码变化如下:

std::vector
    
      > s_statuses;
s_statuses.push_back(
	boost::shared_ptr
     
      (new status(status 1))); s_statuses.push_back( boost::shared_ptr
      
       (new status(status 2))); s_statuses.push_back( boost::shared_ptr
       
        (new status(status 3))); s_statuses.push_back( boost::shared_ptr
        
         (new status(status 4))); s_statuses[1]->break_it(); s_statuses[2]->break_it();
        
       
      
     
    

现在,我们该使用标准库中的哪个适配器了?由于智能指针并没有report成员函数,mem_fun和mem_fun_ref都不能用了。如下代码会编译失败。

std::for_each(
	s_statuses.begin(),
	s_statuses.end(),
	std::mem_fun(&status::report));

我们的好运用完了,标准库并不能帮我们完成这个任务。因此,我们只能借助于之前想避开的for形式或者……Boost.Bind,它可以完全正确地完成任务。

std::for_each(
	s_statuses.begin(),
	s_statuses.end(),
	boost::bind(&status::report,_1));

这与前面的代码是完全一样的(除了容器的名字)。同样的语法可以用于绑定值语义、指针语义或者只能指针。有时候,不同的语法可以帮助我们理解代码,但在我们讨论的情况中不是这样——我们手中的任务是在容器的元素上调用成员函数,没有其他的需求。语法一致的价值是不容轻视的,它既帮助了写代码的人,也帮助了以后维护代码的人。(当然,实际上我们没有写需要维护的代码,但出于参数的考虑,让我们假装是这样做的吧^_^)。

原创:编程实验

#include 
    
     
#include 
     
       #include 
      
        #include 
       
         #include 
        
          #include 
         
           class Status { public: Status(const std::string &name) : name_(name), ok_(true){} void BreakIt() { ok_ = false; } bool IsBroken() const { return ok_; } void Report() const { std::cout << name_ << is << (ok_   ok : broken) << std::endl; } private: std::string name_; bool ok_; }; int main() { std::vector< boost::shared_ptr
          
            > v_spstatus; v_spstatus.push_back(boost::shared_ptr
           
            (new Status(status 1))); v_spstatus.push_back(boost::shared_ptr
            
             (new Status(status 2))); v_spstatus.push_back(boost::shared_ptr
             
              (new Status(status 3))); v_spstatus.push_back(boost::shared_ptr
              
               (new Status(status 4))); v_spstatus[1]->BreakIt(); v_spstatus[2]->BreakIt(); //std::cout << use or: << std::endl; //for (std::vector
               
                ::iterator it = v_spstatus.begin(); it < v_spstatus.end(); it++) //{ // (*it)->Report(); //} //std::cout << use or_each, mem_fun_ref: << std::endl; //std::for_each(v_spstatus.begin(), v_spstatus.end(), std::mem_fun(&Status::Report)); std::cout << use or_each, bind: << std::endl; std::for_each(v_spstatus.begin(), v_spstatus.end(), boost::bind(&Status::Report, _1)); }
               
              
             
            
           
          
         
        
       
      
     
    

总结:

1、标准库中的方法不再能够使用

2、使用share_ptr必须引入头文件#include

这些例子展示了一些Boost.Bind最基本最常用的情况,也是它最擅长的方面。尽管标准库也提供了一些基本工具让我们完成同样的任务,但我们看到Bind提供了语法一致性和一些标准库目前没有的扩展功能。