boost::function的用法
本片文章主要介绍boost::function的用法。 boost::function 就是一个函数的包装器(function wrapper),用来定义函数对象。
1. 介绍
Boost.Function 库包含了一个类族的函数对象的包装。它的概念很像广义上的回调函数。其有着和函数指针相同的特性但是又包含了一个调用的接口。一个函数指针能够在能以地方被调用或者作为一个回调函数。boost.function能够代替函数指针并提供更大的灵活性。
2. 使用
Boost.Function 有两种形式:首选形式和便携式形式, 其语法如下:
首选形式 |
便携式形式 |
---|---|
boost::function<float(int x, int y)>f |
boost::function2<float, int, int>f |
但是便携式形式不是所有的编译器都支持的, 所以这里我只介绍首选形式。
2.1 普通函数
我们可以看下如下的例子:
1 void do_sum(int *values, int n)
2 2 {
3 3 int sum(0);
4 4 for (int i = 0; i < n; ++i)
5 5 {
6 6 sum += values[i];
7 7 }
8 8 cout << sum << endl;
9 9 };
10 10 int _tmain(int argc, _TCHAR* argv[])
11 11 {
12 12 boost::function<void(int *values, int n)> sum;
13 13 sum = &do_sum;
14 14 int a[] = {1,2,3,4,5};
15 15 sum(a, 5);
16 16 return 0;
17 17 }
sum 可以理解为一个广义的函数对象了,其只用就是保存函数do_sum, 然后再调用之。
2.2 成员函数
在很多系统中, 对于类的成员函数的回调需要做特殊处理的。这个特殊的处理就是“参数绑定”。当然这个超出了我们讨论的范围了。 boost::function对于成员函数的使用可以看下如下代码:
1 class X{
2 2 public:
3 3 int foo(int a)
4 4 {
5 5 cout << a <<endl;
6 6 return a;
7 7 }
8 8 };
9 9 int _tmain(int argc, _TCHAR* argv[])
10 10 {
11 11 boost::function<int(X*, int)>f;
12 12 f = &X::foo;
13 13 X x;
14 14 f(&x, 5);
15 15 return 0;
16 16 }
我们发现, 对类的成员函数的对象化从语法是没有多大的区别。
3. 一个典型的例子
上面的几个例子没有体现出boost::function的作用来, 这里在写一个例子。比如当程序执行到某一处的时候想绑定某一个函数, 但是不想立即执行, 我们就可以声明一个函数对象,给此对象绑定相应的函数, 做一些其他事情,然后再来执行绑定的函数, 代码如下:
1 void print(int a)
2 2 {
3 3 cout << a << endl;
4 4 }
5 5 typedef boost::function<void (int)> SuccessPrint;
6 6 int _tmain(int argc, _TCHAR* argv[])
7 7 {
8 8 vector<SuccessPrint> printList;
9 9 SuccessPrint printOne = boost::bind(print, _1);
10 10 printList.push_back(printOne);
11 11 SuccessPrint printTwo = boost::bind(print, _1);
12 12 printList.push_back(printTwo);
13 13 SuccessPrint printThree = boost::bind(print, _1);
14 14 printList.push_back(printTwo);
15 15 // do something else
16 16 for (int i = 0; i < printList.size(); ++i)
17 17 printList.at(i)(i);
18 18 return 0;
19 19 }
上述代码中首先把声明一个函数对象 typedef boost::function<void (int)> SuccessPrint, 然后把print绑定到斥对象中, 放入vector中, 到最后才来执行这print()函数。
- Effective Modern C++翻译(3)-条款2:明白auto类型推导
- React Native在Android平台运行gif的解决方法
- Effective Modern C++翻译(2)-条款1:明白模板类型推导
- Android ormLite复杂条件查询
- Effective Modern C++翻译(1):序言
- C++操作mysql方法总结(2)
- Linux基础(day3)
- C++操作mysql方法总结(1)
- javascript实现最基本、最简单的继承
- C++操作mysql方法总结(3)
- 8.5 输入输出重定向
- Service Worker初体验
- 8.4 通配符
- 8.3 命令补全和别名
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- k8s群集之动态扩缩容——HPA
- k8s群集的三种Web-UI界面部署
- Hive通过Jdbc连接HiveServer2
- SAP Spartacus OccCmsComponentAdapter的findComponentsByIds方法
- 分布式锁:二、Redis锁
- 面试官:kill -9 进程杀不掉,怎么办?
- SAP Spartacus的OccCmsPageNormalizer
- Redis性能指标监控!你知几何?
- Rust FFI 编程 - Bindgen 工具介绍
- synchronized的实现原理——锁膨胀过程
- 大点干!早点散----------rsync+inotify实现远程实时同步
- 听说MongoDB你很豪横?-------------MongoDB数据库基础详解
- 听说MongoDB你很豪横?-------------MongoDB 部署分片群集以及管理分片
- SAP Spartacus和product相关的标准normalizer
- 【Rust 日报】2020-09-09 引入“auditable”