Chinaunix首页 | 论坛 | 博客
  • 博客访问: 779883
  • 博文数量: 239
  • 博客积分: 60
  • 博客等级: 民兵
  • 技术积分: 1045
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-22 18:25
文章分类

全部博文(239)

文章存档

2019年(9)

2018年(64)

2017年(2)

2016年(26)

2015年(30)

2014年(41)

2013年(65)

2012年(2)

分类: C/C++

2013-05-03 18:22:33

    新版C++实现auto关键字, 其实可以在C++98基本的template、sizeof及函数类型重载结合的类型推导方法实现自己恶心的auto,下面的代码取自boost typeof的实现()。在vs2005编译环境调试。

点击(此处)折叠或打开

  1. #include <typeinfo>
  2. #include <iostream>
  3. using namespace std;

  4. struct msvc_extract_type_default_param {};

  5. template<typename ID, typename T = msvc_extract_type_default_param>
  6. struct msvc_extract_type;

  7. template<typename ID>
  8. struct msvc_extract_type<ID, msvc_extract_type_default_param>
  9. {
  10.     template<bool>
  11.     struct id2type_impl;

  12.     typedef id2type_impl<true> id2type;
  13. };

  14. template<typename ID, typename T>
  15. struct msvc_extract_type : msvc_extract_type<ID, msvc_extract_type_default_param>
  16. {
  17.     template<>
  18.     struct id2type_impl<true> //VC8.0 specific bugfeature
  19.     {
  20.         typedef T type;
  21.     };

  22.     template<bool>
  23.     struct id2type_impl;

  24.     typedef id2type_impl<true> id2type;
  25. };

  26. template<typename T, typename ID>
  27. struct msvc_register_type : msvc_extract_type<ID, T>
  28. {
  29. };

  30. #define BOOST_MPL_AUX_NTTP_DECL(T, x) T x

  31. template< BOOST_MPL_AUX_NTTP_DECL(int, N) >
  32. struct int_;

  33. template<int ID>
  34. struct msvc_typeid_wrapper
  35. {
  36.     typedef typename msvc_extract_type<int_<ID> >::id2type id2type;
  37.     typedef typename id2type::type type;
  38. };

  39. //Workaround for ETI-bug for VC6 and VC7
  40. template<>
  41. struct msvc_typeid_wrapper<1>
  42. {
  43.     typedef msvc_typeid_wrapper<1> type;
  44. };

  45. //Workaround for ETI-bug for VC7.1
  46. template<>
  47. struct msvc_typeid_wrapper<4>
  48. {
  49.     typedef msvc_typeid_wrapper<4> type;
  50. };    

  51. //Tie it all together
  52. template<typename T>
  53. struct encode_type
  54. {
  55.     enum:long {value = 2};// by compile time, modify value to implement    type system support multi SELF_TYPEOF using;
  56.     typedef typename msvc_register_type<T, int_<value> >::id2type type;
  57. };

  58. template<class T>
  59. struct sizer
  60. {
  61.     typedef char(*type)[encode_type<T>::value];
  62. };        

  63. template<typename T>
  64. typename sizer<T>::type encode_start(T const&);

  65. template<typename T>
  66. typename sizer<T>::type encode_start(T&);

  67. #define SELF_TYPEOF(expr) \
  68.     msvc_typeid_wrapper<sizeof(*encode_start(expr)) >::type

  69. int main(int argc, char* argv[])
  70. {
  71.     std::string str("this is first str");
  72.     SELF_TYPEOF(str) strAnother("this is another");
  73.     cout<<"the type of strAnother is = "<<typeid(strAnother).name()<<"\tstrAnother value = "<<strAnother.c_str()<<endl;

  74.     SELF_TYPEOF(str) strThird("this is Third");
  75.     cout<<"the type of strThird is= "<<typeid(strThird).name()<<"\tstrThird value = "<<strThird.c_str()<<endl;

  76.     return 0;
  77. }

输出结果为:

点击(此处)折叠或打开

  1. the type of strAnother is = class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >    strAnother value = this is another
  2. the type of strThird is = class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >    strThird value = this strThird Third

(一实现中使用

点击(此处)折叠或打开

  1. template<>
  2.     struct id2type_impl<true> //VC8.0 specific bugfeature
  3.     {
  4.         typedef T type;
  5.     };

中的type来存储类型推导得到的类型
(二使用代码

点击(此处)折叠或打开

  1. template<typename T>
  2. typename sizer<T>::type encode_start(T&);

推导需要的类型。
(三在代码中注册需要的类型

点击(此处)折叠或打开

  1. //Tie it all together
  2. template<typename T>
  3. struct encode_type
  4. {
  5.     enum:long {value = 2};// by compile time, modify value to implement    type system support multi SELF_TYPEOF using;
  6.     typedef typename msvc_register_type<T, int_<value> >::id2type type;
  7. };

其中encode_type中的enum成员value是用来注册的ID。其中,要实现多类型注册,需要在编译时动态索引和改变value值
(四使用代码如下代码从前面注册的类型存储中,得到需要的类型。

点击(此处)折叠或打开

  1. template<class T>
  2. struct sizer
  3. {
  4.     typedef char(*type)[encode_type<T>::value];
  5. };


  6. #define SELF_TYPEOF(expr) \
  7.     msvc_typeid_wrapper<sizeof(*encode_start(expr)) >::type

其中,为得到存储类型,代码

点击(此处)折叠或打开

  1. template<class T>
  2. struct sizer
  3. {
  4.     typedef char(*type)[encode_type<T>::value];
  5. };

充当了索引的功能,使用sizeof来得到存储类型的ID。
  
    所以实现的编译推导顺序是:(二)-> (三)->(一)-> (四),即先推导在注册类型,并使用结构体存储类型,然后根据相应索引在存储结构体中索引得到类型。以上的推导中需编译期改变enum:long {value = 2}中的value值来改进类型推导。
阅读(2264) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~