boost::function用法
来源:互联网 发布:网络语音肝是啥意思 编辑:程序博客网 时间:2024/05/18 23:15
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.Function 用法
- boost::function用法详解
- boost function bind用法
- boost::function用法详解
- boost::function用法详解
- boost::function用法详解
- boost::function用法详解
- boost::function用法详解
- boost::function 用法简介
- boost::function用法详解
- boost::function用法详解
- boost::function用法详解
- boost function的用法
- boost::function用法详解
- boost::function用法
- boost function用法详解
- boost::function的用法
- HDU 5969 最大的位或
- 装tensorflow未果
- 已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出两个集合A和B的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。
- 树莓派和pc通过网线建立内网
- JavaScript之继承
- boost::function用法
- 多态&强制类型转换&抽象类和接口
- 初学如何构建一个小型项目的流程与心得
- 分布式环境下限流方案的实现
- 贪心算法
- 完美解决谷歌浏览器 adobe flash player 已过期
- LDD时间,延时及延缓操作-时间及获取当前时间
- maven spring springmvc 项目
- templates/list.html