boost的typeof 试探

皮贝贝 posted @ 2009年11月27日 05:26 in boost with tags boost typeof , 5664 阅读

前段时间在 csdn 上发了帖子讨论过这个问题,当时讨论了有些地方还是不懂。今天又看了下源码,写下来备忘:(研究 MSVC 的部分)

先看  BOOST_TYPEOF 的主要计算流程:

 

# define BOOST_TYPEOF(expr) \
    boost::type_of::msvc_typeid_wrapper< typeid(boost::type_of::encode_start(expr)) >::type

 

这里主要有三个步骤:

 1. encode_start( expr )。这一步会将 expr 的类型注册, 会形成一个签名的模板类: msvc_typeid_wrapper <typeid(expr)> 类, expr 的 type 就存储在这个类中。

 2.  typeid ( $(1) )。 这一步将第一步计算出的 type 结果(注意,这个结果是函数 encode_start() 返回的,不能直接拿来作类型用)再做 typeid 计算, 生成一个 type_info 对象

 3. msvc_typeid_wrapper< $(3) >。这一步会通过第二部计算出的 type_info 对象来找到注册的对应的 type。完毕。

encode_start

这是个无实作的模板函数,主要完成下列功能:

1. 如果参数的类型没有注册,注册之

2. 返回这个注册的类型

函数的源码:

 

        template<typename T> typename disable_if<
            typename is_function<T>::type,
            typename encode_type<T>::input_type>::type encode_start(T const&);

        template<typename T> typename enable_if<
            typename is_function<T>::type,
            typename encode_type<T>::input_type>::type encode_start(T&);

 

 

暂且不管 is_function.

这个函数主要通过模板类 encode_type 来完成具体功能(两步都有具体的对应语句):

 

        template<typename T>
        struct encode_type
        {
            typedef encode_type<T> input_type;
            //
            // 1步. 类型注册
            typedef typename msvc_register_type<input_type,msvc_typeid_wrapper<typeid(input_type)> >::id2type registered_type;

            // 2步. 返回注册好的类型
            typedef T type;
        };

 

 

类型注册是通过模板类 msvc_register_type 来完成注册,有两个参数,一个是 encode_type 要注册的类型, 注册成另一个参数 msvc_typeid_wrapper, 这样会形成一个 签名为 typeid(encode_type) 的 msvc_typeid_wrapper 签名模板类( 这个模板类中存储有 type )。

至此,形成了一个模板类签名,注册成功了。这里我们知道了 以后就是通过 msvc_typeid_wrapper 类来找到 typeid(expr ) 对应的 type的。

具体注册过程,就更简单了:

 

       template<typename ID>
        struct msvc_extract_type
        {
            struct id2type;
        };

        template<typename T, typename ID>
        struct msvc_register_type : msvc_extract_type<ID>
        {
            typedef msvc_extract_type<ID> base_type;
            struct base_type::id2type // This uses nice VC6.5 and VC7.1 bugfeature
            {
                typedef T type;
            };
        };

 

 

看,就是通过模板的特化来实现的,这是模板的最普遍、最常用的技法。

 

msvc_typeid_wrapper

msvc_typeid_wrapper< typeid(...) >

这个类现在可以看成一个映射集合了,通过 typeid 能找到对应的注册的 type。之所以可以看成映射集合,主要还是 模板的特化起的效果,因为在找类型type之前就完成了模板的特化动作,注册完毕。

msvc_typeid_wrapper 的模板类很简单:

 

       
        template<const std::type_info& ref_type_info>
        struct msvc_typeid_wrapper {
            // 第一步 找到对应的 id2type
            typedef typename msvc_extract_type<msvc_typeid_wrapper>::id2type id2type;
            
            // 第二步 获取 id2type 中的 具体 msvc_typeid_wrapper 签名模板类 
            typedef typename id2type::type wrapped_type;
            // 第三步 从签名类中取得要类型
            typedef typename wrapped_type::type type;
        };

 

 

模板类的参数是 type_info , 这个 type_info 可以作为编译器量参与计算,这点很关键。

 

typeid

 

typeid也和 sizeof一样在编译期完成计算, 返回 一个 type_info 对象, 这个对象是唯一的。

我以前不知道的是这个 typeid 返回的对象可以作为模板类的参数,牢记。

 

 

 

 

 

Avatar_small
boardmodelpaper.com 说:
2024年1月25日 19:30

A sample or model question paper created by educational boards or other institutions for a variety of exams is commonly referred to as the Board model paper. These practice papers give students a sense of the format, degree of difficulty, and kind of material that may be covered in the real exam, helping them get ready for exams. Typically, model papers are written for particular courses or subjects. They cover boardmodelpaper.com a variety of subjects and chapters that are anticipated to have been studied by students during the course of the semester.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter