zoukankan      html  css  js  c++  java
  • 白乔原创:万能类型boost::any

    4.6  使用第三方库

    以上介绍了Visual C++对对象赋值、转换及字符编码转换的方法,实际上还有一些好用的第三方类库用以辅助C++程序员完成对象处理,比较著名的就是boost。本节简单介绍boost库中与数值相关的boost::any、boost::lexical_cast,以及有理数类boost::rational。

    4.6.1  万能类型boost::any

    boost库提供了any类,boost::any是一个能保存任意类型值的类,这一点有点像variant类型,不过variant由于采用了一个巨大的union,效率非常低。而boost利用模板,保存的时候并不改变值的类型,只是在需要的时候才提供方法让用户进行类型判断及取值。

    boost::any几乎可以用来存储任何数据类型:

    1. boost::any ai, as;  
    2. ai = 100;  
    3. as = string("hello"); 

    需要的时候,我们又可以使用any_cast将原来的数据还原:

    1. int i = boost::any_cast<int>(ai);  
    2. string s = boost::any_cast<string>(as); 

    当这种转换发生类型不匹配时,会有异常bad_any_cast发生:

    1. try 
    2. {  
    3.     int i = boost::any_cast<int>(as);  
    4. }  
    5. catch(boost::bad_any_cast & e)  
    6. {  

    在传统的C++程序中,为了支持各种数据类型,我们不得不使用万能指针"void *",但是很遗憾的是,基于万能指针的转换是不安全的,"void*"缺少类型检查。所以,我们建议大家尽量使用any类。

    现在动手

    编写如下程序,体验如何使用boost::any来完成对象类型转换。

    【程序 4-10】使用boost::any完成对象类型转换

    1. 01  #include "stdafx.h" 
    2. 02  #include "boost/any.hpp" 
    3. 03  #include <string>  
    4. 04    
    5. 05  using namespace std;  
    6. 06  using namespace boost;  
    7. 07    
    8. 08  class Cat  
    9. 09  {  
    10. 10  };  
    11. 11    
    12. 12  void print(any it)  
    13. 13  {  
    14. 14      if(it.empty())  
    15. 15      {  
    16. 16          printf("nothing!/r/n");  
    17. 17          return;  
    18. 18      }  
    19. 19    
    20. 20      if(it.type() == typeid(int))  
    21. 21      {  
    22. 22          printf("integer: %d/r/n", any_cast<int>(it));  
    23. 23          return;  
    24. 24      }  
    25. 25    
    26. 26      if(it.type() == typeid(string))  
    27. 27      {  
    28. 28          printf("string: %s/r/n", any_cast<string>(it).c_str());  
    29. 29          return;  
    30. 30      }  
    31. 31    
    32. 32      if(it.type() == typeid(CString))  
    33. 33      {  
    34. 34          _tprintf(_T("CString: %s/r/n"), any_cast<CString>(it));  
    35. 35          return;  
    36. 36      }  
    37. 37    
    38. 38      if(it.type() == typeid(Cat))  
    39. 39      {  
    40. 40          _tprintf(_T("oops! a cat!/r/n"));  
    41. 41          return;  
    42. 42      }  
    43. 43  }  
    44. 44    
    45. 45  int main()  
    46. 46  {  
    47. 47      print(100);  
    48. 48    
    49. 49      any as[] = {any(), 100, string("hello"), CString("world"), Cat()};  
    50. 50      for(int i = 0; i < sizeof(as) / sizeof(as[0]); i++)  
    51. 51      {  
    52. 52          print(as[i]);  
    53. 53      }  
    54. 54    
    55. 55      return 0;56 } 

    结果输出如图4-18所示。

     
    (点击查看大图)图4-18  运行结果

    光盘导读

    该项目对应于光盘中的目录"/ch04/BoostAnyTest"。

    ===========================================

    以上摘自《把脉VC++》第4.6.1小节的内容 ,如果你想与我交流,请点击如下链接加我为好友:http://student.csdn.net/invite.php?u=113292&c=8913f87cffe7d533

  • 相关阅读:
    2018年9月28日CCPC秦皇岛站参赛总结
    数学:二次剩余与n次剩余
    数学:拓展Lucas定理
    BZOJ2301:莫比乌斯反演+二维容斥解决GCD范围计数
    数学:莫比乌斯反演-约数个数和
    数学:莫比乌斯反演-GCD计数
    关于cnblogs至github上blog的搬迁
    友链——一群dalao
    折半搜索(meet in the middle)
    关于爆搜
  • 原文地址:https://www.cnblogs.com/bluejoe/p/5116072.html
Copyright © 2011-2022 走看看