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)
)
);
boost::bind的使用方法的更多相关文章
- 1,Boost -> Bind
#include <boost/bind.hpp> #include <boost/shared_ptr.hpp> #include <iostream> usin ...
- 关于boost::function与boost::bind函数的使用心得
最近开始写一个线程池,期间想用一个通用的函数模板来使得各个线程执行不同的任务,找到了Boost库中的function函数. Boost::function是一个函数包装器,也即一个函数模板,可以用来代 ...
- 使用BOOST BIND库提高C++程序性能
Boost.Bind为函数和函数对象,值语义和指针提供语义了一致的语法.我们首先通过一些简单的例子来看看它的基本用法,之后我们会延伸到嵌套绑定以实现功能组合.理解bind用法的一个关键是理解占位符(p ...
- 手把手教你实现boost::bind
前言 boost::bind操作想必大家都使用过,它特别神奇,能够绑定函数与参数,绑定后能够改变参数数量,并且还可以使用占位符.它可以绑定普通函数也可以绑定类成员函数.好多小伙伴试图看过boost:: ...
- boost asio 学习(二)了解boost::bind
2.了解boost::bind使用boost::bind封装一个函数,考虑以下例子示例2a #include <iostream> #include <boost/bind.hpp& ...
- boost::bind 学习
最近学习了太多与MacOS与Iphone相关的东西,因为不会有太多人有兴趣,学习的平台又是MacOS,不太喜欢MacOS下的输入法,所以写下来的东西少了很多. 等我学习的东西慢慢的与平台无关的时 ...
- boost::bind的使用
最近在几经波折之后,终于对于boost::bind有点理解了.对于习惯了其他语言的人来说,boost::bind是个挺神奇的东西,它可以将你的方法适配成任何其他的方法.其实这得益于c++的模板以及操作 ...
- boost::bind的简单实现
前言 在上一篇blog中简单的实现了boost::function,支持带有2个参数的函数/函数指针,函数对象,函数适配器/bind类,以及带有1个参数的成员函数指针. 本文接着来介绍如何实现一个简单 ...
- boost::function 通过boost::bind调用类成员函数
1. 首先引用boost::function和boost::bind的头文件和库: #include "boost/bind.hpp" #include "boost/f ...
随机推荐
- HTML5API___manifest
离线缓存 manifest 在html标签里面增加个属性 mainfest 就可以告诉浏览器缓存文件在哪里. <html manifest='show.manifest' xmlns=" ...
- js 去除字符串左右两端的空格
<script type="text/javascript"> function trim(str){ //删除左右两端的空格 return str.repl ...
- [Jobdu] 题目1283:第一个只出现一次的字符
题目描述: 在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符. 输入: 输入有多组数据每一组输入一个字符串. 输出: 输出第一个只出现一次的字 ...
- BZOJ 1050 旅行comf
题目如下: 题目描述 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求一条路径,使得路径上最大边 ...
- Mongodb备份(mongodump)和恢复(mongorestore)
1.备份: mongodump -d DbName -o /data/backup 2. 恢复: mongorestore -d newDB --drop data/backup/DbName/
- pexpect-pxssh-登陆Linux-执行命令
#!/usr/bin/python import pexpect import pxssh try: remote=pxssh.pxssh() hostname=raw_input('hostname ...
- [转]Swift 简介 - 苹果最新的编程语言
Swift 真的可以说是最新的编程语言了,2014wwdc刚刚发布,下面来了解一下都有哪些特点. 首先感谢原作者,主要内容是借鉴他的,参考链接 http://zh.lucida.me/blog/an- ...
- Android之ListView性能优化
ListView滚动速度优化主要可以应用以下几点方法来实现: 1.使用Adapter提供的convertView convertView是Adapter提供的视图缓存机制,当第一次显示数据的时候,ad ...
- HDU 3486 Interviewe
题目大意:给定n个数的序列,让我们找前面k个区间的最大值之和,每个区间长度为n/k,如果有剩余的区间长度不足n/k则无视之.现在让我们找最小的k使得和严格大于m. 题解:二分k,然后求RMQ检验. S ...
- windows上放弃使用PyGTK
windows上放弃使用PyGTK - riag的专栏 - 博客频道 - CSDN.NET windows上放弃使用PyGTK 分类: python 2010-03-31 16:47 1054人阅读 ...