Boost bind使用方法
来源:互联网 发布:sql中union的用法 编辑:程序博客网 时间:2024/06/07 02:38
bind是C++98 标准库中函数适配器,bind1st和bind2nd的泛化和增强,可以适配任意的可调用对象,包括函数指针吗, 函数引用,成员函数,指针和函数对象。bind远远超过了STL中的函数绑定,最多可以绑定9个参数,并且对绑定对象要求很低,bind很好的增强了 标准库的功能,已经被收入C++0XTR1草案。
bind 位于boost命名空间
头文件: boost/bind.hpp
原理:bind 是一组重载的函数模板.
用来向一个函数(或函数对象)绑定某些参数.
bind的返回值是一个函数对象,它内部保存f的拷贝,具有operator(),返回类型被自动推导为f的返回类型。发生调用时,这个函数对象将把之前存储的参数转发给f完成调用。
. bind接受的类型为:可以绑定 1.普通函数。2.成员函数。3.成员变量。4.函数对象。5.使用ref库。
bind的真正威力在于他的占位符,他们被分别定义为:_1,_2,_3 一直到_9,位于一个匿名命名空间。
eg:bind(func, _2, _1) (a1, a2); //函数调用发生时,接受真正的参数。 且占位符名字表示在调用式中的顺序,绑定表达式没有顺序要求。
它的源文件太长了.这里提供几个一般用法:
1、绑定普通函数
void fun(int x, int y) { cout << x << ", " << y << endl; }
现在我们看看怎么用bind 向其绑定参数.
对于像 fun 这样的普通函数. 若fun 有n个参数. 则 bind 需要 n+1 个参数: 原始函数的地址 以及 n个要绑定的参数.
向原始函数 fun 绑定所有的参数
boost::bind(&fun, 3, 4) // bind的实参表依次为: 要绑定的函数的地址, 绑定到fun的第一个参数值, 第二个参数值...
这是最简单的绑定, bind表达式存储了fun和3, 4 的拷贝,产生一个临时函数对象。
// 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
eg: 看下面一些例子
int f(int a, int b) { return b + a; };
int g(int a, int b, int c) { return a + b * c; };
typedef int(*f_type) (int, int); //函数指针
typedef int(*g_type) (int, int, int);
//绑定普通函数
std::cout << bind(f, 1, 2) << std::endl; //相当于 f(1, 2);
std::cout << bind(g, 1, 2, 3) << std::endl;
f_type pf = f;
g_type pg = g;
int x = 1, y = 2, z = 3;
std::cout << bind(pf, _1, 9)(x) << std::endl; //(*pf)(x, 9)
std::cout << bind(pg, _3, _2, _2)(x,y,z) << std::endl; //(*pg)(z, y, y)
2 、绑定非静态成员函数
由于成员函数指针不能直接调用operator(),它必须被绑定到一个对象或者指针,然后才能得到this指针进而调用成员函数。因此bind需要牺牲一个占位符的位置,要求用户提供一个类的实例,引用或指针,通过对象作为第一个参数来调用成员函数,即:
bind(&X::func, x, _1, _2, ...); 这时意味着最多只能绑定8个参数
struct A{
void func(int x, int y)
{
cout << x << "," << y << endl;
}
};
A 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, ra, 3, 4)(); //输出 3, 4 //引用
boost::bind(&A::func, pa, 3, 4)(); //输出 3, 4
boost::bind(&A::func, ptr_a, 3, 4)();//输出 3, 4
也可以用boost::bind(&A::func, this, 3, 4)(); //输出 3, 4 形式
同样可以用 _1 这样的占位符. 如:
boost::bind(&A::func, _1, 3, 4)(ptr_a);//输出 3, 4
可以看出. 不论传递给bind 的第2个参数是 对象. 对象指针. 还是智能指针. bind函数都能够正常工作.
同样,bind支持绑定虚成员函数,用法和成员函数相同。
3、绑定成员变量
bind可以绑定public成员变量,就像一个选择器,用法与绑定成员函数类似,只需把成员变量名像一个成员函数一样去使用。
struct point
{
int x, y;
point(int a = 0, int b = 0) : x(a), y(b){}
void print() { std::cout << x << y << std::endl; };
};
vector<point> v(10);
vector<int> v2(10);
transform(v.begin(), v.end(), v2.begin(),bind(&point::x, _1));
4、绑定函数对象
bind可以绑定任意的函数对象(仿函数),包括标准库所有预定义的函数对象。
注意的是:如果函数对象内部定义了返回值类型,则bind可以自动推导出返回值类型,用法和绑定普通函数一样, 如果没有定义,则在绑定形式上做改变,就像这样:boost::bind<void>(f, 3)(); //需要指出返回值的类型 void
标准库和boost库中的大部分函数对象都具有返回值类型的定义,可以直接使用,自定义函数对象指定即可。
bind(std::greater<int>(), _1, 10); //检查x > 10
5、使用ref库
bind采用拷贝的方式绑定对象和参数, 因此bind库可以搭配ref库使用, ref库包装了对象的引用,可以让bind存储对象引用的拷贝,从而降低拷贝代价。
eg: int x = 10;
bind(g, _1, cref(x), ref(x))(10);
f af; //一个函数对象,
bind<int>(ref(af), _1, _2)(10, 20);
6、bind 高级用法
bind嵌套绑定
如果我们有f(x), g(x)两个函数,那么f(g(x))的bind表达式就是:
bind(f, bind(g, _1))(x);
- boost::bind的使用方法
- boost::bind的使用方法
- boost::bind的使用方法
- boost::bind的使用方法
- boost::bind的使用方法
- boost::bind的使用方法
- boost::bind的使用方法
- boost::bind的使用方法
- boost bind的使用方法
- boost::bind的使用方法
- Boost bind使用方法
- [MOC062066]boost bind常见使用方法汇总
- boost库中bind()和function()的使用方法
- boost.bind
- boost::bind
- boost::bind
- boost::bind
- Boost::bind
- NOIP2017模拟赛(10) 总结
- 使用神经网络对黄金期货交割价格进行预测-2 MATLAB
- [积累] 在Ubuntu16.04 64位系统上配置linux-0.11内核实验环境
- SQL查询语句练习题20道
- 6 模型的属性与功能
- Boost bind使用方法
- TCP拥塞控制——慢开始与拥塞避免AIMD
- 使用eclipse时弹出框要求输入用户名和密码
- 初学java时遇到的编译,运行问题
- 大连市血液中心+大连软件园——2017.06.27
- 最小生成树——kruskal
- 介绍一款敲好用的抓包工具Wireshark
- LeetCode
- PHP防止精度丢失