【boost学习】之boost::bind
2014-10-22 01:02
387 查看
Purpose(目的)
原来文档中的purpose完全就是教程了,事实上,bind主要用于改造函数,比如,一个地方需要一个无参的函数,你只有一个以int为参数的函数,并且你知道此时int一直为1就可以了,你怎么办?传统方法,直接实现一个函数,然后以1调用以前的那个int为参数的函数。如下:
当然,这个例子太扯了,我们只需要直接用Fun1(1)调用就可以了,但是bind的目的就是如此,只不过现实中因为各种各样的原因,你的确需要改造函数。再比如下面的情况,你有一个原来写好的函数,接受一个以无参函数为参数,那么,你的Fun1就没有办法派上用场了,那么,传统上,怎么办?如下:
Ok,你不得不写新的函数以满足需求,因为你没有简单的办法改变一个函数的参数。
给个bind的解决方案吧。
需要注意的是,此时不能再使用函数指针了,bind的天生合作伙伴是function,而function是支持函数指针的(如上例所示) 。目的将的很多了,下面看看用法吧(不是什么问题)。
普通函数
最有意思的是,你甚至能用bind来扩充原有函数的参数,见下例:
输出结果:
Argument 1 is 2
sum is 30
arg 1: 10
arg 2: 10
arg 3: 10
---------------------------
sum is 60
arg 1: 20
arg 2: 20
arg 3: 20
---------------------------
sum is 90
arg 1: 30
arg 2: 30
arg 3: 30
---------------------------
sum is 120
arg 1: 40
arg 2: 40
arg 3: 40
---------------------------
函数对象
注意用法中很重要的一条:通常情况下,生成的函数对象的 operator() 的返回类型必须显式指定(没有 typeof 操作符,返回类型无法推导)。(来自Boost文档)
其他的也就很简单了。
成员指针
例子来源于boost文档。
可见bind的强大,支持自己拷贝需要的对象,支持引用,甚至,支持智能指针。
最后一个例子,结合标准库容器及算法的例子,这才是展示bind的强大的地方。
还是来自于boost文档。
例子展示了erase_if,for_each算法中使用bind的方法。
【转自:http://blog.csdn.net/vagrxie/article/details/5509454】
个人总结一下:
(1)bind构造普通函数
(2)bind函数调整参数
(3)bind函数对象(表明返回类型)
(4)bind类的成员函数
原来文档中的purpose完全就是教程了,事实上,bind主要用于改造函数,比如,一个地方需要一个无参的函数,你只有一个以int为参数的函数,并且你知道此时int一直为1就可以了,你怎么办?传统方法,直接实现一个函数,然后以1调用以前的那个int为参数的函数。如下:
void Fun1(int i) { printf(" %d /n " , i); } void FunWeNeed() { Fun1(1 ); } int main() { FunWeNeed(); return 0 ; };
当然,这个例子太扯了,我们只需要直接用Fun1(1)调用就可以了,但是bind的目的就是如此,只不过现实中因为各种各样的原因,你的确需要改造函数。再比如下面的情况,你有一个原来写好的函数,接受一个以无参函数为参数,那么,你的Fun1就没有办法派上用场了,那么,传统上,怎么办?如下:
typedef void FunWeNeed_t(void ); void CallFun( FunWeNeed_t f) { f(); } void Fun1(int i) { printf(" %d /n " , i); } void FunWeNeed() { Fun1(1 ); } int main() { // CallFun(Fun1); // this line can't compile CallFun(FunWeNeed); return 0 ; };
Ok,你不得不写新的函数以满足需求,因为你没有简单的办法改变一个函数的参数。
给个bind的解决方案吧。
#include <boost/bind.hpp> #include <boost/function.hpp> void CallFun( boost::function<void (void )> f) { f(); } void Fun1(int i) { printf(" %d /n " , i); } void FunWeNeed() { Fun1(1 ); } int main() { CallFun(boost::bind(Fun1, 1 )); // this line can't compile CallFun(FunWeNeed); return 0 ; };
需要注意的是,此时不能再使用函数指针了,bind的天生合作伙伴是function,而function是支持函数指针的(如上例所示) 。目的将的很多了,下面看看用法吧(不是什么问题)。
普通函数
最有意思的是,你甚至能用bind来扩充原有函数的参数,见下例:
#include <iostream> #include <boost/bind.hpp> #include <boost/function.hpp> using namespace std; using namespace boost; void f(int a, int b) { cout <<"Argument 1 is " <<a <<endl; } void g(int a, int b, int c) { cout <<"sum is " <<a+b+c <<endl; cout <<"arg 1: " <<a <<endl; cout <<"arg 2: " <<b <<endl; cout <<"arg 3: " <<c <<endl; cout <<"---------------------------" <<endl; } int main() { function<void (int ,int )> f1= bind(f, _2, _1); // 调整参数1,2的位置 f1(1 , 2 ); function<void (int )> sum1 = bind(g, _1, _1, _1); // 3个参数变1个 sum1(10 ); function<void (int , int )> sum2 = bind(g, _2, _2, _2); // 3个参数变2个,仅用一个 sum2(10 , 20 ); function<void (int , int , int )> sum3 = bind(g, _3, _3, _3); // 3个参数还是3个,但是仅用1个 sum3(10 , 20 , 30 ); function<void (int , int , int , int )> sum4 = bind(g, _4, _4, _4); // 3个参数变4个,但是仅用1个 sum4(10 , 20 , 30 , 40 ); return 0 ; };
输出结果:
Argument 1 is 2
sum is 30
arg 1: 10
arg 2: 10
arg 3: 10
---------------------------
sum is 60
arg 1: 20
arg 2: 20
arg 3: 20
---------------------------
sum is 90
arg 1: 30
arg 2: 30
arg 3: 30
---------------------------
sum is 120
arg 1: 40
arg 2: 40
arg 3: 40
---------------------------
函数对象
注意用法中很重要的一条:通常情况下,生成的函数对象的 operator() 的返回类型必须显式指定(没有 typeof 操作符,返回类型无法推导)。(来自Boost文档)
#include <boost/bind.hpp> #include <boost/function.hpp> using namespace std; using namespace boost; struct F { int operator ()(int a, int b) { return a - b; } bool operator ()(long a, long b) { return a == b; } }; int main() { F f; int x = 104 ; function< int (int ) > fun1 = bind<int >(f, _1, _1); // f(x, x), i.e. zero cout <<fun1(1 ); function< bool (long ) > fun2 = bind<bool >(f, _1, _1); // f(x, x), i.e. zero cout <<fun2(1 ); return 0 ; };
其他的也就很简单了。
成员指针
例子来源于boost文档。
#include <iostream> #include <boost/bind.hpp> #include <boost/function.hpp> #include <boost/smart_ptr.hpp> using namespace std; using namespace boost; struct X { void f(int a) { cout <<a <<endl; } }; int main() { X x; shared_ptr<X> p(new X); int i = 1 ; bind(&X::f, ref(x), _1)(i); // x.f(i) bind(&X::f, &x, _1)(i); //(&x)->f(i) bind(&X::f, x, _1)(i); // (internal copy of x).f(i) bind(&X::f, p, _1)(i); // (internal copy of p)->f(i) return 0 ; }
可见bind的强大,支持自己拷贝需要的对象,支持引用,甚至,支持智能指针。
最后一个例子,结合标准库容器及算法的例子,这才是展示bind的强大的地方。
还是来自于boost文档。
class image; class animation { public : void advance(int ms); bool inactive() const ; void render(image & target) const ; }; std::vector<animation> anims; template <class C, class P> void erase_if(C & c, P pred) { c.erase(std::remove_if(c.begin(), c.end(), pred), c.end()); } void update(int ms) { std::for_each(anims.begin(), anims.end(), boost::bind(&animation::advance, _1, ms)); erase_if(anims, boost::mem_fn(&animation::inactive)); } void render(image & target) { std::for_each(anims.begin(), anims.end(), boost::bind(&animation::render, _1, boost::ref(target))); }
例子展示了erase_if,for_each算法中使用bind的方法。
【转自:http://blog.csdn.net/vagrxie/article/details/5509454】
个人总结一下:
(1)bind构造普通函数
(2)bind函数调整参数
(3)bind函数对象(表明返回类型)
(4)bind类的成员函数
相关文章推荐
- 程序开发基础学习三(boost::bind 函数学习)
- 程序开发基础学习三(boost::bind 函数学习)
- Boost学习笔记-bind
- c++ Boost库之boost::bind学习
- 学习 Boost:bind/Boost::functions closure as delegate in C++
- boost 线程学习bind
- Boost程序库学习-bind与function
- 程序开发基础学习三(boost::bind 函数学习)
- boost学习之bind
- C++学习 boost学习之-bind
- c++ Boost库之boost::bind学习
- boost::bind 学习
- Boost学习笔记之五 bind
- C++“准”标准库Boost学习指南(9):Boost.Bind
- Boost学习笔记之bind
- boost::bind 学习
- Boost::bind学习
- boost::bind实现原理学习
- Boost.Python学习笔记
- Boost学习笔记 operators