boost bind使用指南
bind - boost
头文件: boost/bind.hpp
bind 是一组重载的函数模板.
用来向一个函数(或函数对象)绑定某些参数.
bind的返回值是一个函数对象.
它的源文件太长了. 看不下去. 这里只记下它的用法:
9.1 对于普通函数
假如有函数 fun() 如下:
void fun(int x, int y) {
cout << x << ", " << y << endl;
}
现在我们看看怎么用bind 向其绑定参数.
对于像 fun 这样的普通函数. 若fun 有n个参数. 则 bind 需要 n+1 个参数: 原始函数的地址 以及 n个要绑定的参数.
第1种用法:
向原始函数 fun 绑定所有的参数
boost::bind(&fun, 3, 4) // bind的实参表依次为: 要绑定的函数的地址, 绑定到fun的第一个参数值, 第二个参数值...
// fun有多少个参数, 这里就要提供多少个.
表示将 3 和 4 作为参数绑定到 fun 函数.
因为绑定了所有的参数. 现在我们调用bind所返回的函数对象:
boost::bind(&fun, 3, 4)( ); //无参数.
就会输出 3, 4
第2种用法:
向原始函数 fun 绑定一部分参数
boost::bind(&fun, 3, _1) // bind的实参表依次还是: 要绑定的函数的地址, 要绑定到fun的第一个参数值, 然后注意
// 因为我们不打算向fun绑定第2个参数(即我们希望在调用返回的Functor时再指定这个参数的值)
// 所以这里使用 _1 来占位. 这里的 _1 代表该新函数对象被调用时. 实参表的第1个参数.
// 同理下边还会用到 _2 _3 这样的占位符.
这里只为fun绑定了第一个参数3. 所以在调用bind返回的函数对象时. 需要:
boost::bind(&fun, 3, _1)(4); //这个4 会代替 _1 占位符.
输出 3, 4
同理 boost::bind(&fun, _1, 3)(4);
输出 4, 3
第3种用法:
不向 fun 绑定任何参数
boost::bind(&fun, _1, _2) // _1 _2 都是占位符. 上边已经说过了.
所以它就是 将新函数对象在调用时的实参表的第1个参数和第2个参数 绑定到fun函数.
boost::bind(&fun, _1, _2)(3, 4); // 3将代替_1占位符, 4将代替_2占位符.
输出 3, 4
同理 boost::bind(&fun, _2, _1)(3, 4); // 3将代替_1占位符, 4将代替_2占位符.
会输出 4, 3
同理 boost::bind(&fun, _1, _1)(3); // 3将代替_1占位符
会输出 3, 3
对于普通函数就这些. 对于函数对象. 如:
struct Func {
void operator()(int x) {
cout << x << endl;
}
} f;
绑定的时候可能要指出返回值的类型:
boost::bind<void>(f, 3)(); //指出返回值的类型 void
9.2 对于非静态成员函数
假如有:
struct A {
void func(int x, int y) {
cout << x << "," << y << endl;
}
};
A a;
A* pa = new A; //指针
boost::shared_ptr<A> ptr_a(pa); //智能指针.
现在要向像 A::func 这样的非静态成员函数绑定.
若A::func有n个参数, 则 bind 要有 n+2 个参数: 指向成员函数fun的指针, 绑定到this的对象, n个参数.
如:
boost::bind(&A::func, a, 3, 4)(); //输出 3, 4
boost::bind(&A::func, pa, 3, 4)(); //输出 3, 4
boost::bind(&A::func, ptr_a, 3, 4)();//输出 3, 4
同样可以用 _1 这样的占位符. 如:
boost::bind(&A::func, _1, 3, 4)(ptr_a);//输出 3, 4
可以看出. 不论传递给bind 的第2个参数是 对象. 对象指针. 还是智能指针. bind函数都能够正常工作.
9.3 bind嵌套
有个类如下. 记录人的信息:
class Personal_info {
string name_;
int age_;
public:
int get_age();
string name();
};
vector<Personal_info> vec;
...
现在要对 vec 排序. 可以用 bind 函数做一个比较谓词
std::sort(
vec.begin(),
vec.end(),
boost::bind(
std::less<int>(),
boost::bind(&personal_info::age,_1), //_1 占位符是 sort 中调用比较函数时的第一个参数.
boost::bind(&personal_info::age,_2))); //_2 占位符是 sort 中调用比较函数时的第二个参数.
9.4 函数组合
假如有:
vector<int> ints;
...
想用 std::count_if() 来求ints中有多少是 >5 且 <=10 的. 这在常规代码中通常就要写一个函数来实现这个谓词:
if (i>5 && i<=10) ...
现在用bind则可以:
std::count_if(
ints.begin(), ints.end(),
boost::bind(
std::logical_and<bool>(),
boost::bind(std::greater<int>(),_1,5),
boost::bind(std::less_equal<int>(),_1,10)));
9.5 绑定到成员变量
有:
map<int, string> my_map;
my_map[0]="Boost";my_map[1]="Bind";
现在要输出所有元素的 second 成员. 也就是输出这些字符串. 其中的打印函数如下:
void print_string(const string& s) {
std::cout << s << '/n';
}
则可以:
for_each(
my_map.begin(),
my_map.end(),
boost::bind(
&print_string,
boost::bind(&std::map<int,std::string>::value_type::second,_1)
)
);
汗... 看不懂bind的源码. 也不知是如何实现这些功能的. 只能等<<boost源码剖析>>出来了.
注意:
(以下补于08年6月3日)
boost::bind() 返回的函数对象会保存要绑定的实参. 而且总是拷贝一份以值的方式保存..
这主要是考虑到被绑定的实参的生命期.
但这并不总是我们期望的. 例如有时我们希望它保存指针或引用:
有函数:
void f(int & x) { ++x; }
然后:
int n = 0;
bind(&f, n)(); //我们希望 n==1 . 但实际上没有这样...
要避免这种对象复制. 而 要bind得到的函数对象保存实参的引用语义. 可以:
使用 boost::ref() 或 boost::cref() 如
bind(&f, ref(n))(); //OK, 执行后 n==1
如果是绑定一个对象到它的成员函数上. 如:
A a;
bind(&A::fun, a); //则保存的是 a对象的拷贝.
要避免这种拷贝. 除了上面提到的 ref() 外, 也可以:
bind(&A::fun, &a); //用指针. 反正用对象和用指针都可以. 而用指针可以避免对象拷贝的问题.
注意: (以下补于6月10日)
bind () 的第一个参数——被绑定函数——是不被求值的. 如下例:
typedef void (*pf)(int);
std::vector<pf> v; //v中有一些函数指针.
std::for_each(v.begin(), v.end(), bind(_1, 5)); //想实现 _1(5); 这样的调用. 但这样不行!
正确的做法是借助 boost::apply 模板(来自boost/bind/apply.hpp).
apply也是一个函数对象. 它的作用如下:
apply<void> a; //模板参数为函数对象的返回值类型.
a(x); //相当于调用 x();
a(x, y); //相当于调用 x(y);
a(x, y, z); //相当于调用 x(y, z);
所以错误的bind应该写为:
std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));
boost bind使用指南相关推荐
- c++ Boost库之boost::bind学习
刚开始学c++,就看boost库其实有点小小的不情愿. 团队要求必掌握的Boost库: boost::bind boost::function boost::Signals2 学习前奏:在写关于coc ...
- boost::bind 介绍
boost::bind 介绍 这篇文章介绍boost::bind()的用法, 文章的主要内容是参考boost的文档. 1. 目的 boost::bind 是std::bindlist 和 std::b ...
- 展示使用 boost bind 和 phoenix 处理删除的不同方法的测试程序
展示使用 boost bind 和 phoenix 处理删除的不同方法的测试程序 实现功能 C++实现代码 实现功能 展示使用 boost bind 和 phoenix 处理删除的不同方法的测试程序 ...
- Boost:boost :: bind相等运算符的测试程序
Boost:boost :: bind相等运算符的测试程序 实现功能 C++实现代码 实现功能 boost :: bind相等运算符的测试程序 C++实现代码 #include <boost/c ...
- boost::bind时候注意性能问题
原文地址:http://hi.baidu.com/hpagent/blog/item/471b7d92dc8ac39ca977a4dc.html 测试一下,看看例子 #include <iost ...
- 【Boost】以boost::function和boost:bind取代虚函数
这是一篇比较情绪化的blog,中心思想是"继承就像一条贼船,上去就下不来了",而借助boost::function和boost::bind,大多数情况下,你都不用上贼船. boos ...
- boost::function和boost:bind取代虚函数
这是一篇比较情绪化的blog,中心思想是"继承就像一条贼船,上去就下不来了",而借助boost::function和boost::bind,大多数情况下,你都不用上贼船. boos ...
- Please use boost/bind/bind.hpp + using namespace boost::placeholders
The practice of declaring the Bind placeholders (_1, _2, -) in the global namespace is deprecated. P ...
- ROS下的多参数调用,boost::bind使用
主要是当我们订阅一个消息时候,会调用一个返回函数. 例如: 1 ros::Subscriber scan_sub=n.subscribe<std_msgs::Int8>("/te ...
最新文章
- CodeForces - 1459D Glass Half Spilled(dp)
- java中报错convension_LambdaConversionException与泛型:JVM错误?
- ORACLE使用copy方式存储迁移,详细讲解Oracle数据库的数据迁移方法
- 软件工程 敏捷的酒后问答
- php ios 判断字符串长度,iOStextfield 限制输入字符长度和过滤表情符号
- java vector 线程安全_关于Vector到底是不是 线程安全的 问题
- HEVC---CompressCU 函数解析
- mysql基础之mariadb集群主从架构
- atlas 力矩计算_Atlas 2.1.0 实践(2)—— 安装Atlas
- 测试压缩ASP.NET中的ViewState
- 微信小程序布局 左右结构简单例子
- 计算机导论学后感5000字,计算机导论学习心得体会
- C64x EDMA Architecture
- 瑞云Rayvision渲染的原创动画《吃饭睡觉打豆豆》震撼来袭 ——创造产业历史,日点击量过200万次...
- 本地计算机无法设置共享文件夹,win10系统下共享文件夹无法访问的解决方法
- 2019-9-29 opencv摄像机标定与三维重构4-Depth Map from Stereo Images立体图像中的深度图(视差图)
- 大夏shell编程学习笔记(5)
- Qtcreator远程调试arm开发板程序指南
- 基础化工行业报告:国内盐湖提锂产业进程加速,产业链有望受益
- 《云计算网络珠玑》新书有奖试读活动
热门文章
- python中重要的模块asyncio
- android+多米音乐+自动播放,android 高仿多米音乐播放器
- linux下java调用matlab程序,linux_java调用windows_matlab程序
- layui分页limit不显示_小心避坑:MySQL分页时使用 limit+order by 会出现数据重复问题...
- Java中如何引用另一个类里的集合_【18期】Java序列化与反序列化三连问:是什么?为什么要?如何做?...
- html 禁止缩放 ios10,完美解决ios10及以上Safari无法禁止缩放的问题
- 小鑫の日常系列故事(十)——排名次_JAVA
- Programming Computer Vision with Python (学习笔记七)
- JQuery 总结(6) 锋利的jQuery
- spring事物配置,声明式事务管理和基于@Transactional注解的使用