笔记-std::function<> && std::bind()



 参考博客

http://hi.baidu.com/webidea/item/d7cc8db2e4149174244b0961

http://blog.csdn.net/qq575787460/article/details/8531397

    在C++的TR1中(Technology Report)中包含一个function模板类和bind模板函数,使用它们可以实现类似函数指针的功能,但却却比函数指针更加灵活,特别是函数指向类的非静态成员函数时。可以参考Scott Meyers. <<Effective C++ (3rd Edition)>>. Item 35.下面具体说明其使用方法。

一、指向全局函数或静态成员函数时

因为在本质上讲全局函数和静态成员函数没有区别,使用方法上除了静态成员函数在引用时要在前面加域作用符className::外,没有其它任何区别,事实上全局函数也有可能放入命名空间,或者使用全局域作用符,例如 nameSpace::function() 或::function,这样不仅本质上相同,形势上也与静态成员函数一致了,所以它们是没有区别的,放到一起讨论。

  1. typedef std::function<void ()> fp;  
  2. void g_fun()  
  3. {  
  4.     cout<<"g_fun()"<<endl;  
  5. }  
  6. class A  
  7. {  
  8. public:  
  9.     static void A_fun_static()  
  10.     {  
  11.         cout<<"A_fun_static()"<<endl;  
  12.     }  
  13.     void A_fun()  
  14.     {  
  15.         cout<<"A_fun()"<<endl;  
  16.     }  
  17.     void A_fun_int(int i)  
  18.     {  
  19.         cout<<"A_fun_int() "<<i<<endl;  
  20.     }  
  21.   
  22.     //非静态类成员,因为含有this指针,所以需要使用bind  
  23.     void init()  
  24.     {  
  25.         fp fp1=std::bind(&A::A_fun,this);  
  26.         fp1();  
  27.     }  
  28.   
  29.     void init2()  
  30.     {  
  31.         typedef std::function<void (int)> fpi;  
  32.         //对于参数要使用占位符 std::placeholders::_1  
  33.         fpi f=std::bind(&A::A_fun_int,this,std::placeholders::_1);  
  34.         f(5);  
  35.     }  
  36. };  
  37. int main()  
  38. {  
  39.     //绑定到全局函数  
  40.     fp f2=fp(&g_fun);  
  41.     f2();  
  42.   
  43.     //绑定到类静态成员函数  
  44.     fp f1=fp(&A::A_fun_static);  
  45.     f1();  
  46.   
  47.     A().init();  
  48.     A().init2();  
  49.     return 0;  

        静态成员函数与非静态成员函数的参数表不一样,原型相同的非静态函数比静态成员函数多一个参数,即第一个参数this指针,指向所属的对象,任何非静态成员函数的第一个参数都是this指针,所以如果把static void A_fun_static()  前面的static去掉,其函数原型等效于下面的一个全局函数:

void A_fun_static(A* this)  ;


二、std::tr1::bind()模板函数的使用

通过上面的std::tr1::function 可以对静态成员函数进行绑定,但如果要对非静态成员函数的绑定,需用到下机将要介绍的bind()模板函数.

首先说bind的用法,其声明如下所示:

    bind(Function fn, T1 t1, T2 t2, …, TN tN);

其中fn为将被调用的函数,t1…tN为函数的参数。如果不指明参数,则可以使用占位符表示形参,点位符格式为

std::tr1::placehoders::_1,  std::tr1::placehoders::_2,  …,  std::tr1::placehoders::_N

将上例中static void A_fun_static() 前的static去掉改为非静态成员函数即void A_fun_int() 形式,则进行动态绑定使得程序正常运行,则调用为

        fpi f=std::bind(&A::A_fun_int,this,std::placeholders::_1);  

std::bind绑定到虚函数时会表现出多态行为。

对于虚成员函数的情况与上面第2节所说相同,仍然可以实现虑函数的效果。如果定义类Square继承自Rectangle,将Rectangle::OnEvent重载,定义一个新的Square::OnEvent,Rectangle::initialize中的函数不变,仍然使用Rectangle::OnEvent进进绑定,则调用成员object.onEvent()时,具体执行Rectangle::OnEvent还是Square::OnEvent,看object所属对象的静态类型是Rectangle还是Square而定

  1. typedef std::function<void ()> fp;  
  2.   
  3. class A  
  4. {  
  5. public:  
  6.     virtual void f()  
  7.     {  
  8.         cout<<"A::f()"<<endl;  
  9.     }  
  10.   
  11.     void init()  
  12.     {  
  13.         //std::bind可以表现出多态行为  
  14.         fp f=std::bind(&A::f,this);  
  15.         f();  
  16.     }  
  17. };  
  18. class B:public A  
  19. {  
  20. public:  
  21.     virtual void f()  
  22.     {  
  23.         cout<<"B::f()"<<endl;  
  24.     }  
  25. };  
  26. int main()  
  27. {  
  28.     A* pa=new B;  
  29.     pa->init();  
  30.   
  31.     return 0;  
  32. }  


foobar(4, 2)
Foo::bar(4, 2)
lambda::Foo::bar(4, 2)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值