zoukankan      html  css  js  c++  java
  • VC8 的 type_traits 关键字 zz

    VC8 的 type_traits 关键字

    引言
     
    type traits 用来在编译期间获取类型的信息,在 boost 库中用了很多诡异的方法来检测,主要是模板特化机制,比如两个类型是否一直:
     
    template <typename T1, typename T2>
    struct is_same
    {
        static const bool value = false;
    };
    template <typename T>
    struct is_same<T, T>
    {
        static const bool value = true;
    };
     
    一个普通版本的模板,一个特化的,就可以区分传入的类型是否一致:
    int*p = is_same<int, long>::value; // 编译成功,因为false是有效的空指针常量
    int*p = is_same<int, int>::value; // 编译错误,因为true不是指针。
    如果要实现检测是否是整数呢?
    template <typename T>
    struct is_integral
    {
        static const bool value = false;
    };
     
    template <> struct is_integral <bool>{   static const bool value = true; };
    template <> struct is_integral <char>{   static const bool value = true; };
    template <> struct is_integral <wchar_t>{   static const bool value = true; };
    template <> struct is_integral <signed char>{   static const bool value = true; };
    template <> struct is_integral <unsigned char>{   static const bool value = true; };
    template <> struct is_integral <short>{   static const bool value = true; };
    template <> struct is_integral <unsigned short>{   static const bool value = true; };
    template <> struct is_integral <int>{   static const bool value = true; };
    template <> struct is_integral <unsigned int>{   static const bool value = true; };
    template <> struct is_integral <long>{   static const bool value = true; };
    template <> struct is_integral <unsigned long>{   static const bool value = true; };
    ...
     
    发现还遗漏了一点,就是类型加上 cv 限制后跟原来的类型不一致,那么 is_interal<const int>::value 就不再为真,所以,要修正这个bug,还需要特化:
    template <> struct is_integral <const int>{   static const bool value = true; };
    template <> struct is_integral <volatile int>{   static const bool value = true; };
    template <> struct is_integral <const volatile int>{   static const bool value = true; };
    好吧,那先把上面的在扩大三倍再说吧。
     
    这些都比较容易实现,复杂的就需要根据一些规则来推算,如果不是这个,又不是那个,又不是……,那么就是某物,比如判断是否是自定义的类类型:
    不是内置类型
    不是数组
    不是指针
    不是引用
    不是函数
    不是函数指针
    不是成员函数
    不是成员函数指针
    那么一定是类类型。
     
    麻烦吗?更麻烦的还有呢。
     
    比如如何判断是不是 enum,是不是 union?办法有,不过是越来越复杂。
     
    再比如如何判断是不是 POD 类型,尤其是判断 POD 类型,对模板库的性能有较大帮助,因为 POD 类型可以直接用
    memcpy 搬移,不需要构造和析构。很遗憾,有些用上面的规则无法推出。
     
    其实这些信息就在编译器内部,与其偷偷摸摸地检测,这样不但慢而且容易出错,不如直接问编译器要,据说 sgi 的编译器老早就实现了一些编译器内置的 type traits 支持,
    现在好消息来了,VC 2005 也支持了:
     
    不过 VC 2005 也只支持了一些用模板特化机制难以检测,列表如下:
    __has_assign( type )
    __has_copy( type )
    __has_finalizer( type )
    __has_nothrow_assign( type )
    __has_nothrow_constructor( type )
    __has_nothrow_copy( type )
    __has_trivial_assign( type )
    __has_trivial_constructor( type )
    __has_trivial_copy( type )
    __has_trivial_destructor( type )
    __has_user_destructor( type )
    __has_virtual_destructor( type )
    __is_abstract( type )
    __is_base_of( base , derived)
    __is_class( type )
    __is_convertible_to( from , to )
    __is_delegate( type )
    __is_empty( type )
    __is_enum( type )
    __is_interface_class( type )
    __is_pod( type )
    __is_polymorphic( type )
    __is_ref_array( type )
    __is_ref_class( type )
    __is_sealed( type )
    __is_simple_value_class( type )
    __is_union( type )
    __is_value_class( type )
    特别感谢 ctrlz@newsmth 提供信息,VC 2005 发布快两年了,还没把它的扩展语法都看一遍,真是惭愧。
     
  • 相关阅读:
    《 动态规划_ 货币系统 》
    《动态规划_入门 LIS 问题 》
    数据库中左连接、右连接、全连接的区别
    http和https的区别与联系
    【复习周之流水账记录】
    web前端整套面试题(三)--网易的面试题
    微信小程序相关三、css写小黄人
    CSS选择器的匹配规则
    web前端整套面试题(二)--今日头条面试题
    有趣的逻辑题
  • 原文地址:https://www.cnblogs.com/cutepig/p/1409995.html
Copyright © 2011-2022 走看看