C++ 下 typeof 的实现 – findumars

C++ 下 typeof 的实现 – findumars

如今我们家有如此的长度指定遗传密码:

  1. std::vector<int> arr;  
  2. for(std::vector<迭代器(=);!ITER)
  3. {  
  4.     
  5. }  

内脏局促不安直线显微镜凝块计数坏人维修业务的std::vector::iterator,由于我们家不晓得典型(自动地),它是读写。。

C++11下有typeof和auto保留字,因而,乱如上述的第三线的评价会相称轻易:

  1. std::vector<int> arr;  
  2. (汽车为ITER =();ITER!ITER)
  3. {  
  4.     
  5. }  

在VC(2005、2008、2010)不支撑物两个折叶词;gcc(先前)支撑物typeof,但缺席汽车。

假设有typeof的话,汽车可以仿照非常奇特的复杂了,这么成绩的折叶点相信方式履行typeof。


一、需求报户口id的typeof

在C++里,除非以下几件事可以计算表现的典型在汇编T:

1. sizeof
这件事是很强的,蔑视是什么神情的屁股,在汇编时都走快特赞的典型和恢复典型一定尺寸的。。
2. typeid
假定你不适用C RTTI效能,typeid将计算表现的典型在汇编时,并恢复任一援用到type_info。

适用第一种办法,我们家可以接到任一数字,假如数字是独特的的典型,因而,我们家可以经过它获取典型。。
如此写:

  1. template <typename T>  
  2. struct Type2ID;  
  3. template <int id>  
  4. struct ID2Type;  
  5.   
  6. template <typename T>  
  7. Type2ID encode(const T
  8. template <typename T>  
  9. Type2ID编码(T
  10.   
  11. #define type_of(…) \  
  12.     ID2Type<sizeof(encode((__VA_ARGS__)))>::type_t  

适用变化的限制因素宏的账目,目的在于需求能支撑物传入的限制因素如C。

解说任一虚行使职责编码线6-9,符合把__VA_ARGS__的典型取暴露。sizeof运算符抵押权了encode并无能力的真正被家具到。

为了让指定遗传密码在我们家前面的任务,还需求适用报户口某个典型的模板机制:

  1. register_type(典型解说, n) \  
  2.     template <> \  
  3.     struct Type2ID { 性格的ID的[ ]
  4.     template <> \  
  5.     struct ID2Type    { typedef type type_t; };  
  6.   
  7. REGISTER_TYPE(int,    1)  
  8. REGISTER_TYPE(long,   2)  
  9. REGISTER_TYPE(char,   3)  
  10. REGISTER_TYPE(double, 4)  

我们家如今可以支撑物int、long、静态典型推断焦和双表达。。


二、自动地分派id的typeof

眼前,我国履行type_of可以任务,但在任务先前,不可避免的先报户口很多典型,您还需求为每个典型分派独特的的ID。。不报户口典型不克不及静态的引出物。
加法运算适用的是MPL库,实现register_type指引航线,到每种典型的自动地化成boost_type_of分派任一独特的的ID。不如此我们家手头上,适用某个轻量级的东西。

如上所述,typeid,是任一地租的身份证建筑者,sizeof也有同类的的效能。
纵然多态类经遗传获得是在汇编时运转忘记,除非输出的客体。我们家可以适用操纵来处置这个成绩,typeid恢复任一操纵典型在汇编时type_info。

上面我们家开端实作可以自动地分派id的typeof。率先,我们家需求把type_info和成型。:

  1. template <const std::type_info& type_id>  
  2. struct TypeID {};  
  3.   
  4. #define type_id(…) TypeID  

因此从typeid的典型的类模板:

  1.   
  2. template<typename ID>  
  3. 安排汲取
  4.   
  5. #define type_extract(…) \  
  6.     Extract::type_t  

典型的编码典型是报户口:

  1.   
  2. template <typename T>  
  3. 安排编码typedef T* type_t; };  
  4.   
  5. template <typename T>  
  6. typename Encode::type_t encode(const T
  7. template <typename T>  
  8. typename Encode::type_t编码(T

相同编码防伪技术适用,同时,一种操纵典型的编码。

溶出型:

  1.   
  2. template <typename T>  
  3. 安排解码
  4. template <typename T>  
  5. 安排解码 { typedef T type_t; };  
  6.   
  7. #define type_of(…) \  
  8.     Decode::type_t  

这边适用解码典型来编码更改后。。

适用编码、为了解码,为了应对typeid客体上可以使分叉运转时。

不要以为C 的模板自动地样式可以写在这:

  1. template<typename T>  
  2. 安排汲取typeid(T*)> >  
  3. {  
  4.     typedef T* type_t;  
  5. };  

汇编器将告知我们家任一不能变更的的偶发误差。。假定可以自动地推断,因此我们家会节省有雅量的的活力未来的。

容许汲取酬劳传入的典型通知,我们家不可避免的留下印象典型,但缺席必要散布ID。:

  1. register_type(典型解说) \  
  2.     template<> \  
  3.     安排汲取 { typedef type* type_t; };  
  4.   
  5. REGISTER_TYPE(int)
  6. REGISTER_TYPE(长)
  7. REGISTER_TYPE(char)
  8. REGISTER_TYPE(双)

你可以尺寸,typeid能否能实现汇编期的典型自动地引出物。为了解说这个成绩,指定遗传密码适用客体检测多机组合形式的冲撞:

  1. class A  
  2. {  
  3. public:  
  4.     virtual func() { std::cout无法律效力<< “A” << std::endl; }  
  5. };  
  6. REGISTER_TYPE(A)  
  7.   
  8. class B : 大众
  9. {  
  10. public:  
  11.     virtual func() { std::cout无法律效力<< “B” << std::endl; }  
  12. };  
  13. REGISTER_TYPE(B)  
  14.   
  15. 诠释主震相
  16. {  
  17.     B bb;  
  18. a = aa=BB
  19. type_of(AA)CC
  20.     ();  
  21.   
  22.     return 0;  
  23. }  

在VC汇编器(2005、2008、2010、2012)汇编后,我们家将接到任一乐曲味。


三、全自动地的typeof

写一排register_type这不是任一大成绩。,话虽这样说写这条线或任一参加低的的事。
履行自动地报户口,为了处置任一成绩:方式适用const type_info和特意的模板吗?

侥幸的是,有某个小灵巧,可以用VC。,我们家可以尝试在任一类的里面特别化任一类模板:

  1.   
  2. struct empty_t {};  
  3.   
  4. template<typename ID, typename T = empty_t>  
  5. 安排汲取
  6.   
  7. template<typename ID>  
  8. 安排汲取  
  9. {  
  10.     template <bool>  
  11.     struct id2type;  
  12. };  
  13.   
  14. template<typename ID, typename T>  
  15. 安排汲取 : Extract  
  16. {  
  17.     template <>  
  18.     struct id2type<true> { typedef T type_t; };  
  19. };  
  20.   
  21. #define type_extract(…) \  
  22.     Extract::id2type<true>::type_t  

这一招是实质,在类模板和类模板,而且适用经遗传获得让“特别化在特别化中见效”。这部戏是在GCC汇编但,它会紧握你正研究特别化任一坐下非大局且非namespace区域的类模板。再别焦急。,假如VC可以适用它。

因而我们家可以写报户口任一类模板:

  1.   
  2. template<typename T, typename ID>  
  3. 安排汲取留下印象:  
  4. {  
  5.     typedef typename id2type<true>::type_t type_t;  
  6. };  

它将经过经遗传获得的Extract自动地特别化出任一存有典型通知的id2type。

前面的事实复杂,不过轻蔑地顺应编码:

  1. template <typename T>  
  2. 安排编码
  3. {  
  4.     typedef T* enc_type_t;  
  5.     typedef Register reg_type;  
  6.     typedef typename reg_type::type_t type_t;  
  7. };  

如今type_of可以直线作用于任何一个表达,在汇编的时分自动地派生典型。

扫尾任务:

对vc和GCC举行明显的的处置,解说汽车:

  1. #ifdef __GNUC__  
  2. #define type_of(…) __typeof((__VA_ARGS__))  
  3. #else  
  4. #define type_of(…) \  
  5.     Decode::type_t  
  6. #endif  
  7. 解说汽车(名字, …) type_of(__VA_ARGS__) name((__VA_ARGS__))  

我们家不可避免的记着在前面写的那些的类模板最适当的任务和。,应在#对立的事物时间。


请参阅有关主题:

请参考书指定遗传密码:

更多容量,请接见:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Message *
Name*
Email *