Boost学习笔记之bind

来源:互联网 发布:八大处 知乎 编辑:程序博客网 时间:2024/05/17 22:59

bind绑定某个类的方法,以函数的方法使用某个类的方法。

一 Boost::bind
   
   在STL中,我们经常需要使用bind1stbind2st函数绑定器和fun_ptr,mem_fun等函数适配器,这些函数绑定器和函数适配器使用 起来比较麻烦,需要根据是全局函数还是类的成员函数,是一个参数还是多个参数等做出不同的选择,而且有些情况使用STL提供的不能满足要求,所以如果可以 我们最好使用boost提供的bind,它提供了统一的接口,提供了更多的支持,比如说它增加了shared_ptr,虚函数,类成员的绑定。

二 源码剖析

 1) bind1st,bind2st函数绑定器,把二元函数对象变为一元函数对象。
 2) mem_fun,把成员函数变为函数对象。
 3) fun_ptr,把一般的全局函数变为函数对象。
 4) boost::bind(),包含了以上所有的功能。


三 实例

 1)区别与mem_funfun_ptr 


#include <functional>#include <iostream>#include <string>#include "boost/bind.hpp"class some_class {public:          void print_string(const std::string& s) const    {            std::cout << s << '\n';     }    void print_classname()    {        std::cout << "some_class" << std::endl;   }};void print_string(const std::string s) {  std::cout << s << '\n';}void print_functionname(){    std::cout << "Print_functionname" <<std::endl;}int main() {      std::ptr_fun(&print_string)("hello1");    //std::ptr_fun<void>(&print_functionname);    some_class sc0;    std::mem_fun_ref(&some_class::print_classname)(sc0);    std::mem_fun_ref<void,some_class>(&some_class::print_classname)(sc0);    //std::mem_fun1_ref<void,some_class,const std::stirng>(&some_class::print_string)(sc0,"hello2");    (boost::bind(&print_string,_1))("Hello func!");      boost::bind(&print_functionname);    some_class sc;      (boost::bind(&some_class::print_classname,_1)(sc));    (boost::bind(&some_class::print_string,_1,_2))(sc,"Hello member!");}


2)区别与bind1stbind2st

#include <functional>#include <iostream>#include <string>#include <vector>#include <algorithm>#include "boost/bind.hpp"void main(){    std::vector<int; ints;    ints.push_back(7);    ints.push_back(4);    ints.push_back(12);    ints.push_back(10);    int count=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))        );    std::cout << count << '\n';    std::vector<int>::iterator int_it=std::find_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))        );    if (int_it!=ints.end())     {  std::cout << *int_it << '\n';}}


 3)区别传ref和传instance

// bind instance or reference#include <functional>#include <iostream>#include <string>#include <vector>#include <algorithm>#include "boost/bind.hpp"class tracer {public:     tracer() {    std::cout << "tracer::tracer()\n";  }     tracer(const tracer& other) {    std::cout << "tracer::tracer(const tracer& other)\n";  }     tracer& operator=(const tracer& other)    {    std::cout <<      "tracer& tracer::operator=(const tracer& other)\n";    return *this;  }     ~tracer() {    std::cout << "tracer::~tracer()\n";     }     void print(const std::string& s) const    {    std::cout << s << '\n';  }};void main(){    tracer t;    boost::bind(&tracer::print,t,_1)(std::string("I'm called on a copy of t\n"));    tracer t1;    boost::bind(&tracer::print,boost::ref(t1),_1)(  std::string("I'm called directly on t\n"));}

 4)绑定虚函数

//bind vitual class function#include <functional>#include <iostream>#include <string>#include <vector>#include <algorithm>#include "boost/bind.hpp"class base {public:    virtual void print() const     {    std::cout << "I am base.\n";      }      virtual ~base() {}};class derived : public base {public:     void print()const     {    std::cout << "I am derived.\n";  }};void main(){    derived d;    base b;    boost::bind(&base::print,_1)(b);    boost::bind(&base::print,_1)(d);}


 5)绑定成员变量

// bind class's member#include <functional>#include <iostream>#include <string>#include <vector>#include <algorithm>#include "boost/bind.hpp"class personal_info {     std::string name_;      std::string surname_;    unsigned int age_;public:     personal_info(const std::string& n,const std::string& s,unsigned int age):name_(n),surname_(s),age_(age) {}     std::string name() const {return name_;}     std::string surname() const {return surname_;}     unsigned int age() const {return age_;}};void main(){ std::vector<personal_info> vec; vec.push_back(personal_info("Little","John",30)); vec.push_back(personal_info("Friar", "Tuck",50)); vec.push_back(personal_info("Robin", "Hood",40)); std::sort(vec.begin(),     vec.end(),     boost::bind(std::less<unsigned int>(),boost::bind(&personal_info::age,_1),boost::bind(&personal_info::age,_2))     ); std::sort(vec.begin(),     vec.end(),     boost::bind(std::less<std::string>(),boost::bind(&personal_info::surname,_1),boost::bind(&personal_info::surname,_2))     );}

四 注意

 1) 现在的类库最多可以支持9个参数。
 2)在绑定一个成员函数时,bind 表达式的第一个参数必须是成员函数所在类的实例!理解这个规则的最容易的方法是,这个显式的参数将取替隐式的 this ,被传递给所有的非静态成员函数。细心的读者将会留意到,实际上这意味着对于成员函数的绑定器来说,只能支持八个参数,因为第一个要用于传递实际的对象。

3)当我们传递某种类型的实例给一个 bind 表达式时,它将被复制,除非我们显式地告诉 bind 不要复制它。要避免复制,我们必须告诉bind 我们想传递引用而不是它所假定的传值。我们要用 boost::ref 和 boost::cref (分别用于引用和 const 引用)来做到这一点,它们也是Boost.Bind 库的一部分。还有一种避免复制的方法;就是通过指针来传递参数而不是通过值来传递。

 4) 通过 Boost.Bind, 你可以象使用非虚拟函数一样使用虚拟函数,即把它绑定到最先声明该成员函数为虚拟的基类的那个虚拟函数上。这个绑定器就可以用于所有的派生类。如果你绑定到其它派生类,你就限制了可以使用这个绑定器的类。

5bind还可以绑定成员变量。

五 参考

1Beyond the C++ Standard Library: An Introduction to Boost
2boost在线document

原文链接:http://www.cppblog.com/mzty/archive/2007/09/05/31622.html


原创粉丝点击