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 ...
随机推荐
- 关于如何使用three.js的小教程<一>
昨天看了看three.js这个东西,身为一个3D引擎,他还是非常强大的.官网上有个tutorial讲的不甚具体.http://aerotwist.com/tutorials/getting-start ...
- .net mvc System.Web.Optimization 、System.Data.Entity.Infrastructure找不到
在MVC4的开发中,如果在App_Start目录下BundleConfig.cs类没有找不到引用System.Web.Optimization,可以使用程序包管理控制台进行安装到使用的项目 打开 工具 ...
- SMACSS:一个关于CSS的最佳实践-1.Overview
什么是SMACSS? SMACSS(发音"smacks"),全称Scalable and Modular Architecture for CSS.顾名思义,SMACSS是一个可扩 ...
- 文件上传下载样式 --- bootstrap
在平时工作中,文件上传下载功能属于不可或缺的一部分.bootstrap前端样式框架也使用的比较多,现在根据bootstrap强大的样式模板,自定义一种文件下载的样式. 后续会使用spring MVC框 ...
- 传统web和mvc的区别
- POJ 1459 Power Network(网络流 最大流 多起点,多汇点)
Power Network Time Limit: 2000MS Memory Limit: 32768K Total Submissions: 22987 Accepted: 12039 D ...
- zoj 3714 Java Beans
/*很简单的一题,求连续的m位,求总和最多的值,循环找一下,就出来了*/ #include<stdio.h> ]; int main(int argc, char* argv[]) { i ...
- chroot命令
CHROOT就是Change Root,也就是改变程序执行时所参考的根目录位置.通过chroot机制来更改某个进程所能看到的根目录,即将某进程限制在指定目录中,保证该进程只能对该目录及其子目录的文件有 ...
- Java Socket 入门2 Java与C# Socket 通信
参考http://www.cnblogs.com/cdtarena/p/3184313.html 这里以C#作为服务端 其实不论C#是服务端还是客户端都不是主要问题 毕竟不论客户端还是服务端 都包括 ...
- 射频识别技术漫谈(15)——Mifare1的安全性及7字节序列号M1卡
Mifare1的安全性主要指卡中数据的安全性,要求卡中的数据不能被非法修改或窃听.数据的安全性主要使用加密技术来保证,加密技术有两个关键因素:加密算法和密钥.现代加密技术的一大特点是加密算法公开,如果 ...