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

时间:2022-09-08 19:44:11

这是一篇介绍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();
}

 

 

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