• C++ 下 typeof 的实现


    现在我们有这样一坨代码:

    C++11下有typeof和auto关键字,于是像上面第3行那样纠结的位置可以变得简单不少:

    假如有typeof的话,auto可以很简单的模拟出来,那么问题的关键点在于如何实现typeof。


    一、需要注册id的typeof

    在C++里,可以在编译期计算表达式类型的只有下面两个东西:

    1. sizeof
        这东西很强大,不论后面的表达式是什么,均可以在编译期正确得到类型并直接返回类型大小。
    2. typeid
        若不使用C++的RTTI功能,typeid会在编译期计算出表达式的类型,并返回一个type_info引用。

    使用第一种方法,我们可以得到一个数字,只要这个数字对类型而言是唯一的,那么我们就可以通过它反向得到类型。
    类似这样写:

    第6-9行定义了假函数encode,负责把__VA_ARGS__的类型取出来。sizeof运算符保证了encode并不会真正被执行到。

    为了让我们前面的代码可以工作,还需要使用模板特化的机制注册一些类型:


    二、自动分配id的typeof

    目前我们实现的type_of虽然可以工作,但在干活之前必须要先注册一大堆类型,而且还需要给每个类型分配一个唯一的id。没有注册的类型是无法动态推导的。
    boost里使用了mpl库里的一些东西,完成了REGISTER_TYPE的过程,自动化的给每个放入BOOST_TYPE_OF里的类型分配了唯一的id。我们手头上没有这么NX的东西,只好使用一些轻量级的玩意了。

    比如上面提到的typeid,就是个不错的id生成器,也具有sizeof类似的功能。
    虽然多态类继承的情况会让typeid在编译期失效,但只限于传入对象的情况。我们可以使用指针规避这个问题,typeid将在编译期返回一个指针类型的type_info。

    下面我们开始实作可以自动分配id的typeof。首先,我们需要一个可以把type_info&变成类型的玩意:

    最后把类型解出来:

    使用Encode、Decode的目的,是为了绕过typeid对对象可能进行的运行时处理。

    不要妄想C++的模板自动推导可以这样写:

    为了让Extract能够认得传入的类型信息,我们得注册我们的类型,但是不再需要传入id了:


    三、全自动的typeof

    虽然仅仅写一行REGISTER_TYPE已经不是什么大问题了,但多写这一行还是一个让人不爽的事情。
    想要实现全自动注册,得解决一个麻烦的问题:如何通过const type_info&特化模板?

    幸好vc里还有一些小花招可以利用,我们可以尝试在一个类的内部特化一个类模板:

    这样我们就可以写出一个专门用于注册的类模板:

    [cpp] view plaincopy
     
    1. /* 
    2.     Register a type 
    3. */  
    4.   
    5. template<typename T, typename ID>  
    6. struct Register : Extract<ID, T>  
    7. {  
    8.     typedef typename id2type<true>::type_t type_t;  
    9. };  


    它将通过继承的Extract自动特化出一个存有类型信息的id2type。

    后面的事情就简单了,只需要稍微改写一下Encode:

    扫尾工作:

    区别对待vc和gcc,并定义auto:


    相关内容请参考:

    http://svn.boost.org/svn/boost/trunk/boost/typeof/msvc/typeof_impl.hpp

    文章代码请参考:

    http://neonx.googlecode.com/svn/trunk/neoncore/type/typeof.h

    更多内容请访问:

    http://darkc.at

    http://blog.csdn.net/markl22222/article/details/10474591

  • 相关阅读:
    [No00009C]Visual Studio在 解决方案资源管理器 里同步定位打开的文件
    [No00009B]win10快捷键大全
    [No000099]软件版本命名规范
    [No000098]SVN学习笔记5-分支,合并,属性,补丁,锁,分支图
    [No000097]程序员面试题集【下】
    [No000096]程序员面试题集【上】
    [No000095].Net入门级逆向工程-1.SpreadsheetGear汉化
    [No000093]按住Alt 再按数字键敲出任意汉字和字符!
    [No000092]SVN学习笔记3-Import/Checkout(迁入/迁出),GetLock(加锁)
    ubuntu 查看端口被占用并处理
  • 原文地址:https://www.cnblogs.com/findumars/p/5017820.html
Copyright © 2020-2023  润新知