• C++11 type_traits 之is_same源码分析


    请看源码:

    template<typename _Tp, _Tp __v>
        struct integral_constant
        {
          static const _Tp                      value = __v;
          typedef _Tp                           value_type;
          typedef integral_constant<_Tp, __v>   type;
        };
      
      /// typedef for true_type
      typedef integral_constant<bool, true>     true_type;
    
      /// typedef for false_type
      typedef integral_constant<bool, false>    false_type;
    
    
    
    template<typename, typename>
        struct is_same
        : public false_type { };
    
      template<typename _Tp>
        struct is_same<_Tp, _Tp>
        : public true_type { };

    1. is_same是模版,integral_constant也是模版

    2. true_type和false_type是integral_constant实例化的类型

    3.is_same通用的模版继承了false_type

    4.is_same的偏特化模版继承了true_type

    5.is_same模版实参类型一致时,会实例化偏特化模版,而偏特化模版继承了true_type

    6.integral_constant<bool, true> 即truetype的value是true

    is_same和static_assert配合使用,可以在编译期进行强大的类型检查。使用例子如下:

      1 struct A{~A(){cout<<"delete A..."<<endl;}};
      2 template<typename T>
      3 struct TypeTraits
      4 {
      5        typedef void TYPE;
      6 };
      7 template<>
      8 struct TypeTraits<std::string>
      9 {
     10        typedef std::string TYPE;
     11 };
     12 template<>
     13 struct TypeTraits<long>
     14 {
     15        typedef long TYPE;
     16 };
     17 template<>
     18 struct TypeTraits<A>
     19 {
     20        typedef A TYPE;
     21 };
     22 template<>
     23 struct TypeTraits<double>
     24 {
     25 
     26        typedef double TYPE;
     27 };
     28 
     29 
     30 class DeleteLong
     31 {
     32 public:
     33     void operator()(void *p)
     34     {
     35         delete static_cast<long*>(p);
     36     }
     37 };
     38 class DeleteString
     39 {
     40 public:
     41     void operator()(void *p)
     42     {
     43         delete static_cast<string*>(p);
     44     }
     45 };
     46 class DeleteDouble
     47 {
     48 public:
     49     void operator()(void *p)
     50     {
     51         delete static_cast<double*>(p);
     52     }
     53 };
     54 class DeleteA
     55 {
     56 public:
     57     void operator()(void *p)
     58     {
     59         delete static_cast<A*>(p);
     60     }
     61 };
     62 
     63 class ExportData
     64 {
     65     void* vp;
     66     enum my_type {SP,LP,DP,AP} types;
     67     static unordered_map<type_index,my_type> typeMap;
     68     static vector<function<void(void*)>> deleters;
     69 public:
     70 
     71     template <typename T> ExportData(const T& t)
     72     {
     73         static_assert(is_same<typename TypeTraits<T>::TYPE,T>::value,"not support!");
     74         vp=new T(t);
     75         types= typeMap[typeid(T)];
     76     }
     77     template <typename T> void setData(const T& t)
     78     {
     79         static_assert(is_same<typename TypeTraits<T>::TYPE,T>::value,"not support!");
     80         assert(types==typeMap[typeid(T)]);
     81         *(static_cast<T*>(vp))=t;
     82     }
     83     template <typename T> void getData(T& t)
     84     {
     85         static_assert(is_same<typename TypeTraits<T>::TYPE,T>::value,"not support!");
     86         assert(types==typeMap[typeid(T)]);
     87         t=*(static_cast<T*>(vp));
     88     }
     89 
     90     ~ExportData()
     91     {
     92        (deleters[types])(vp);
     93     }
     94 
     95 };
     96 
     97 unordered_map<type_index,ExportData::my_type> ExportData::typeMap
     98 {
     99     {typeid(string),ExportData::my_type::SP},
    100     {typeid(long),ExportData::my_type::LP},
    101     {typeid(double),ExportData::my_type::DP},
    102     {typeid(A),ExportData::my_type::AP}
    103 };
    104 vector<function<void(void*)>> ExportData::deleters {DeleteString(),DeleteLong(),DeleteDouble(),DeleteA()};

    static_assert(is_same<typename TypeTraits<T>::TYPE,T>::value,"not support!");静态断言,当用户使用不支持类型时,立即阻止用户编译。

  • 相关阅读:
    UPC2018组队训练赛第十二场
    ACM-ICPC 2018南京赛区网络预选赛
    UPC2018组队训练赛第十一场
    UPC2018组队训练赛第十场
    UPC2018组队训练赛第九场
    linux 用简单密码
    设置分辨率
    packstack
    rbenv
    elasticsearch
  • 原文地址:https://www.cnblogs.com/tangzhenqiang/p/4128597.html
Copyright © 2020-2023  润新知