boost::function用法
Posted 「临江仙」
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了boost::function用法相关的知识,希望对你有一定的参考价值。
1.回调基础
对于回调,目前c++支持的有回调函数,函数对象,lambda函数三种方式。
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。对于函数对象和lambda函数也是类似的使用方法。
一个排序的函数可以这样定义:
template <typename T>
void sort(int a[], int n, T fun)
...
fun(a, b);
...
函数指针:
typedef bool(*compare_ptr)(int a, int b);
bool compare(int a, int b)
return a > b;
调用时sort(a, 10, compare);
函数对象:重载其()操作符
class Compare
bool operator ()(int a, int b)
return a > b;
;
使用方法可以为sort(a, 10, Compare()),使用时将产生一个临时的对象。
lambda函数:
这样使用sort: sort(a, 10, [](int a, int b)return a >b;)
2.boost function 统一三种回调方式
上面的模板函数sort已经统一了三者的调用,但是表现的很不直观。
boost function也是一个模板类,用这个类的对象来封装上述三者,达到回调统一的效果。
定义一个boost::function的对象:
typedef boost::function<bool(int, int)> COMPARE_FUN;
COMPARE_FUN boost_fun;
其定义方式可以看出这是一个类模板,<返回值(参数1,参数2,...)>
我们可以这样使用:
排序函数的定义为 void sort(int a[], int n,COMPARE_FUN fun);
可以将函数指针,函数对象,lambda函数赋值给boost::function
函数指针:boost_fun = compare;
函数对象:boost_fun = Compare();
lambda函数:boost_fun = [](int a, int b)(return a > b);
3.函数对象拷贝
boost::funtion的强大作用有一点是于对类和对象的操作
boost::function在绑定函数对象时,其实是对每一个对象都进行了一次拷贝
也就是boost::function会拥有一个单独的函数对象,看下面这个例子
class FunObject
int m_total;
public:
FunObject():m_total(0)
int operator()(int addition)
m_total += addition;
return m_total;
void print_me()
std::cout << m_total << std::endl;
;
int main()
FunObject ob;
ob.print_me();
boost::function<int(int)> fun_1;
fun_1 = ob;
std::cout << fun_1(100)<< std::endl;
ob.print_me();
boost::function<int(int)> fun_2;
fun_2 = ob;
std::cout << fun_2(100) << std::endl;
ob.print_me();
结果是:
0
100
0
100
0
boost::function并没有对原来的对象产生改变,因为它拷贝了一份对象。
boost::ref用来让boost::function对象持有原来的引用:fun = boost::ref(ob);
4.类的成员函数
对于类的成员函数,boost也提供了相关的类模板进行处理。
其实,对于c++成员函数,也只是隐藏了this指针的C函数,不难想到,这一块的类模板第一个参数必须是类的对象,引用或者指针。
boost::function<void(FunObject&)> fun_1;
boost::function<void(FunObject*)> fun_2;
fun_1 = &FunObject::print_me;
fun_2 = &FunObject::print_me;
FunObject ob;
fun_1(ob);
fun_2(&ob);
5.boost::bind
boost::bind返回一个boost::function对象,function与bind的配合使用,能设计出扩展性很强的程序模块。
看下面这个例子:
class A
int m_a;
int m_b;
public:
A():m_a(1), m_b(2)
void add(int a, int b)
m_a += a;
m_b += b;
std::cout << m_a << std::endl;
std::cout << m_b << std::endl;
;
int main()
A ob;
boost::function<void(int a, int b)> fun = boost::bind(&A::add, &ob, _1, _2);
fun(10, 20);
boost::bind绑定成员函数,第一个参数是函数的地址,后面的参数按照顺序为函数的参数。_1,_2是相关的宏,表示调用时使用的参数的顺序,fun(10,20) 10是_1位置的参数, 20是_2位置的参数。
比如可以这样写:
A ob;
boost::function<void(A*, int a, int b)> fun = boost::bind(&A::add, _1, _2, _3);
那么调用的时候得fun(&ob, 10, 20);
也可以这样:
A ob;
boost::function<void(A*, int a, int b)> fun = boost::bind(&A::add, _1, _2, 20);
那么调用的时候得fun(&ob, 10);
有没有觉得很神奇,如果是这样的申明add(int a, int b, int c)
还可以这样写:
A ob;
boost::function<void(int a, int b)> fun = boost::bind(&A::add, &ob, _1, _2, 30);
fun(10, 20);
boost::function与bind的结合,可以帮助我们使用自己想要的参数,不局限于定义好的函数申明。
小结
1.boost::function可以实现回调方式的统一,bing可以控制自定义参数,可以方便设计出易于扩展的程序。
2.存在额外消耗,对于所有的回调都组织成了一个function对象,同时function对象里还存在着一些拷贝,特别是函数对象的拷贝。
以上是关于boost::function用法的主要内容,如果未能解决你的问题,请参考以下文章
boost::factory 和 std::function