C++11新特性之std::function & std::bind

std::function

在c++98&03时我们通常使用回调函数来处理一些需要某种场景下才触发的回调操作,但回调函数有一个限制就是它只能赋值给同类型的全局或者静态函数,对于其他有相同的返回值和相同类型参数的成员函数不能赋值。

[cpp]  view plain  copy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. //define a callback func  
  5. typedef void(*CALL_BACK)(void);  
  6.   
  7. //global func  
  8. void show(void)  
  9. {  
  10.     cout << "show global func" << endl;  
  11. }  
  12.   
  13. class A  
  14. {  
  15. public:  
  16.     //member func  
  17.     void show_class_num(void ){ cout << "show member func" << endl; }  
  18.   
  19.     //static member func  
  20.     static void show_class_num_static(void ){ cout << "show static member func" << endl; }  
  21. };  
  22.   
  23. int main()  
  24. {  
  25.     CALL_BACK call;  
  26.     //assign a global func to callback func  
  27.     call = show;  
  28.     call();  
  29.     //error   
  30.     call = A::show_class_num;  
  31.   
  32.     //assign a static member func  
  33.     call = A::show_class_num_static;  
  34.     call();  
  35.     return 0;  
  36. }  
在了解C++11中引入的std::function前,首先我们需要了解C++中有关可调用实体(callable target)的相关概念,C++中包含了几种可调用对象:函数,函数指针,lambda表达式,std::bind创建的对象,以及重载了()操作符的类。函数以及函数指针这个就不用介绍了,有关lambda表达式也是C++11引入的一个新特性,就地创建匿名表达式,读者可以参阅相关介绍lambda的文章,我后续也会写一篇关于lambda的详解,这个需要说的是重载了操作符()的类也称为可调用对象。

[cpp]  view plain  copy
  1. // 仿函数(functor)  
  2. class Functor  
  3. {  
  4. public:  
  5.     int operator()(int a)  
  6.     {  
  7.         return a;  
  8.     }  
  9. }  
这个类也称为仿函数类。

C++11中引入了std::funtion这个模板类,这个模板类是一个多用途的函数包裹器,std::function的实例可以存储,拷贝和调用任何的可调用实体,包括全局函数,成员函数,lambda表达式和仿函数以及std::bind绑定的对象,甚至是成员变量,std::function统一和简化了相同类型可调用实体的使用方式,使得编码变得更简单。

std::function的原型:

template< class R, class... Args >
class function<R(Args...)>
R是返回值类型,Args是函数的参数类型,实例一个std::function对象很简单,就是将可调用对象的返回值类型和参数类型作为模板参数传递给std::function模板类。比如:

std::function<void()> f1;

std::function<int (int , int)> f2;

std::function的使用

[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include <functional>  
  3.   
  4. using namespace std;  
  5.   
  6. std::function<int(void)> func;  
  7.   
  8. int testFunc()  
  9. {  
  10.     cout << "global Func" << endl;  
  11.     return 0;  
  12. }  
  13.   
  14. auto lambda = [](void) -> int {cout << "lambda func" << endl; return 0; };  
  15.   
  16. class Func  
  17. {  
  18.   
  19.     int operator()(void)  
  20.     {  
  21.         cout << "仿函数" << endl;  
  22.         return 0;  
  23.     }  
  24. };  
  25.   
  26.   
  27. class CFuntion  
  28. {  
  29. public:  
  30.     int ClassMember(){ cout << "class member function" << endl; return 0; }  
  31.     int static StaticClassFunc(){ cout << "static class member function" << endl; return 0; }  
  32. };  
  33. int main()  
  34. {  
  35.     func = testFunc;  
  36.     func();  
  37.   
  38.     func = lambda;  
  39.     func();  
  40.   
  41.     func = CFuntion::StaticClassFunc;  
  42.     func();  
  43.   
  44.     CFuntion classFunc;  
  45.     func = std::bind(&CFuntion::ClassMember, classFunc);  
  46.     func();  
  47.   
  48.     return 0;  
  49. }  
可见std::function的使用其实是很简单的,只要创建一个模板类对象,病传入相应的模板参数就可以存储任何具有相同返回值和参数的可调用对象,在调用的时候直接将std::function对象加上()就可以调用存储在其中的可调用实体,需要注意的是创建的std::function对象中存储的可调用实体不能为空,若对空的std::function进行调用将抛出   std::bad_function_异常。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值