boost::function
来源:互联网 发布:免费虚拟主机空间php 编辑:程序博客网 时间:2024/05/01 17:46
function的概念
function是一个函数对象的“容器”,概念上像是c/c++中函数指针类型的泛化,是一种“只能函数指针”。它以对象的形式封装了原始的函数指针或函数对象,能够容纳任意符合函数签名的可调用对象。因此它可以被用于回调机制,暂时保管函数或函数对象,在之后需要的时机再调用。
function可以配合bind/lambda使用,存储bind/lambda表达式的结果,使其可以被多次调用。
function的声明
function只需要一个模板参数,这个参数就是将要容纳的函数类型,例如
function<int()> func;
将声明一个可以容纳返回值为int,无参数的function对象。
这种声明很容易理解,在尖括号中的类型声明就像一个没有函数名的函数原型。
function的函数声明也可以像真的函数声明那样带有参数名。例如:
function<int (int a,int b,int c)> func2;
与
function<int (int,int,int)> func2;
是完全等价的。
用法
function的构造函数可以接受任意符合模板中声明的函数类型的可调用对象,例如函数指针和函数对象,或者是另一个function对象的引用。
无参数的构造函数或传入空指针构造将创建一个空的function对象,不持有任何可调用物。调用空的function对象将抛出bad_function_call异常,因此在使用function前好检测其有效性(empty(),operator!)。
示范function 基本用法的代码如下:
#include <boost/function.hpp>using namspace boost;int f(int a,int b){ return a+b;}int main(){ function<int(int, int)> func; //无参数构造function对象 assert(!func); func = f; assert(func.contains(&f)); if(func) { cout<<func(10,20); } func = 0; assert(func.empty());}
只要函数签名式一致,function也可以存储成员函数和函数对象,或者是bind/lambda表达式。假设我们有如下的一个类demo_class,它既有普通成员函数,又重载了operator():
struct demo_class{ int add(int a,int b) { return a+b; } int operator()(int x) const { return x*x; }};
存储成员函数时,可以直接在function声明的函数签名式中指定类的类型,然后用bind绑定成员函数:
function<int(demo_class&,int,int)> func1; func1 = bind(&demo_class::add,_1,_2,_3); demo_class sc; cout<<func1(sc,10,20);
我们也可以在函数类型中仅写出成员函数的签名,在bind时直接绑定类的实例:
function<int(int,int)> func2; func2 = bind(&demo_class::add,&sc,_1,_2); cout<<func2(10,20);
用于回调
function可以容纳任意符合函数签名式的可调用物,因此它非常适合代替函数指针,存储用于回调的函数。
作为示范,我们定义一个demo_class类,它使用function代替函数指针作为内部类型保存回调函数,存储形式为void(int)的可调用物。
class demo_class{private: typedef function<void(int)> func_t; func_t func; int n;publicL: demo_class(int i) :n(i) {} /* 使用模板函数accept()接受回调函数。之所以使用模板函数,是因为这种形式更加灵活,用户可以在不关心也不知道内部存储形式的情况下,传递任何可调用对象,包括函数指针和函数对象。 */ template<typename CallBack> void accept(CallBack f) { func = f; } //成员函数run()用于回调函数 void run() { func(n); }};
接下来我们定义一个用于回调的函数,它将输入翻番:
void call_back_func(int i){ cout<<"call_back_func:"; cout<<i*2<<endl;}
demo_class的回调可以这样使用:
int main(){ demo_class dc(10); dc.accept(call_back_func); dc.run();}
function可以搭配bind,把bind表达式作为回调函数,可以接受类成员函数,或者把不符合函数签名式的函数bind转为可接受的形式。下面定义一个回掉函数工厂类,它有两个回掉函数:
class call_back_factory{public: void call_back_func1(int i) { cout<<"call_back_factory1:"; cout<<i*2<<endl; } void call_back_func2(int i,int j) { cout<<"call_back_factory2:"; cout<<i*j*2<<endl; }}
function搭配bind的用法如下:
int main(){ demo_class dc(10); call_back_factory cbf; dc.accept(bind(&call_back_factory::call_back_func1,cbf,_1)); dc.run(); dc.accept(bind(&call_back_factory::call_back_func2,cbf,_1,5)); dc.run();}
通过以上代码可以看到,function无需改变回调的接口就可以解耦客户代码,使客户代码不必绑死在一种回调形式上。
- boost::function
- Boost.Function
- boost::function
- boost:function
- boost::function
- boost::function
- Boost.Function
- boost::function<>
- boost::function
- 【Boost】boost::function介绍
- boost::bind\boost::function
- 【Boost】boost::function介绍
- 【Boost】boost::function介绍
- 【Boost】boost::function介绍
- 【Boost】boost::function介绍
- boost::bind/boost::function
- boost::function和boost::bind
- boost::function 和boost::bind
- 欢迎使用CSDN-markdown编辑器
- UIPopoverController如何使用(选自CocoaChina)
- power designer pdm生成sql脚本和数据库
- shape与selector的结合使用
- 【树】Trie树
- boost::function
- HNOI 2013 bzoj 3144 切糕
- jquery简洁篇
- 如何配置以太坊PoA私有链
- 调用平台删除选择行数据方法注意事项
- Angularjs自定义指令之三级联动---地理位置的选择
- iOS中几种数据持久化方案
- string类型中的erase()
- 优化理论