boost::bind 和 boost::function 基本用法

这是一篇介绍bindfunction用法的文章,起因是近来读陈硕的文章,提到用bindfunction替代继承,于是就熟悉了下bindfunction的用法,都是一些网上都有的知识,记录一下,期冀对他人也有用处

注:本文暂时不探索bindfunction的实现和开销。

 1. bind 是什么

boost::bind std::bindlist 和 std::bind2nd的结合体。它提供一个任意的函数对象(仿函数)、函数、函数指针、成员函数指针。 它可以绑定任意的参数。bind 没有对函数对象有任何的要求。

 2. bind 到函数/函数指针

void print(int array[], int size)
{
  for (int i = 0; i < size; i++) {
    printf("%d\n", array[i]);
  }
}

int main(int argc, const char *argv[])
{
  int array[]= {1,2,1,34,5,5,56,9,6,10};
  int len = sizeof(array)/sizeof(array[0]);
  // 绑定普通函数

  boost::bind(print, _1,_2)(array, len);
  // 与function结合

  boost::function<void(int [], int)> fn = boost::bind(print, _1,_2);
  fn(array, len);
return 0; }

注意,_1 和_2 表示占位符。

3. bind到类成员函数

class Thread {p
public: Thread (int id):thread_id(id) {} virtual void Run() { printf("this is threads %d\n", thread_id); } private: int thread_id; }; class CallWrapper { public: typedef boost::function<void ()> CallBack; CallWrapper (); static void Run(CallBack fn) { printf("%s\t%d\n", __FUNCTION__, __LINE__); fn(); } }; int main() { Thread worker(10); // 绑定类成员函数,worker相当于this指针 boost::bind(&Thread::Run, worker)(); // 作为参数,参数用function CallWrapper::Run(boost::bind(&Thread::Run, worker)); }

上面是一个比较简单的市立,下面给出一个比较适用的分行读取文件的例子  

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <stdio.h>
#include <string>
#include <map>

class SimpleLineReader {
public:
  SimpleLineReader (const string& filename)
  {
    fp_ = fopen(filename.c_str(), "r");
  }
  ~SimpleLineReader (){
    if (fp_) {
      fclose(fp_);
    }
  }
  typedef boost::function<bool (const std::string& line)> Callback;
  bool ProcessLines(Callback fn)
  {
    if (!fp_)
    {
      return false;
    }
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    while ((read = getline(&line, &len, fp_)) != -1) {
      string str(line, read);
      fn(line);
    }
    free(line);
    return true;
  }
private:
    FILE* fp_;
};

class CityLoader {
public:
  CityLoader (){}
  int init(const std::string& filename)
  {
    SimpleLineReader reader(filename);
    reader.ProcessLines(boost::bind(&CityLoader::ProcessLine, this, _1));
    printf("readline\t%d\n", city_map_.size());
  }
  ~CityLoader ()
  {
  }
private:
  bool ProcessLine(const std::string& line)
  {
    static int cnt = 0;
    if (line.empty())
    {
      return true;
    }
    city_map_.insert(make_pair(++cnt, line));
    return true;
  }
  std::map<int, std::string> city_map_;
};
void test_simple_line_reader()
{
  CityLoader city_loader;
  city_loader.init("data/city.txt");
}
int main()
{
    test_simple_line_reader();
}

 

 

 这就是全部了。个人认为比较方便。

posted @ 2014-08-17 10:57  westfly  阅读(3845)  评论(0编辑  收藏  举报