代码之家  ›  专栏  ›  技术社区  ›  Soo

模板类型派生

  •  0
  • Soo  · 技术社区  · 8 年前

    我需要使用模板实现一个类,比如“MyClass”。

    template<class T>
    class MyClass
    {
    public:
    
    
              T var1;
              T1 var2;
            };
    

    有两个成员变量var1和var2。如果类模板参数“T”是基本类型(例如:float、double或long double),则变量var1和var2的类型应与模板参数相同。在上述示例中,即T1=T。

    但是如果模板参数是 std::complex<T> ,我想要

    T var1;
    std::complex<T> var2;
    

    如何在C++11中实现它?

    1 回复  |  直到 7 年前
        1
  •  7
  •   max66    8 年前

    一个可能的解决方案是定义一个简单的类型特征来提取正确的类型

    template <typename T>
    struct myTypeTraits
     { using type = T; };
    
    template <typename T>
    struct myTypeTraits<std::complex<T>>
     { using type = T; };
    

    MyClass 成为

    template <typename T>
    class MyClass
     {
       using T0 = typename myTypeTraits<T>::type;
    
       T0 var1;
       T  var2;
     };
    

    如果你想确定 T 是一种基本类型(或者你是指算术?),有点复杂。

    一种可能的方法是定义一个类型特征( true false )如果类型是 std::complex

    template <typename>
    struct isComplex : public std::false_type
     { };
    
    template <typename T>
    struct isComplex<std::complex<T>> : public std::true_type
     { };
    

    下一个修改 myTypeTraits 带有声明(无通用定义)和 默认布尔值

    template <typename T, bool = std::is_fundamental<T>::value, 
                          bool = isComplex<T>::value>
    struct myTypeTraits;
    

    接下来的两个专门化,第一个用于基础知识,第二个用于复数类型

    template <typename T>
    struct myTypeTraits<T, true, false>
     { using type = T; };
    
    template <typename T>
    struct myTypeTraits<std::complex<T>, false, true>
     { using type = T; };
    

    这个 类名 类保持相等,但如果您尝试用(通过示例)一个 std::string .

    #include <complex>
    #include <type_traits>
    
    template <typename>
    struct isComplex : public std::false_type
     { };
    
    template <typename T>
    struct isComplex<std::complex<T>> : public std::true_type
     { };
    
    template <typename T, bool = std::is_fundamental<T>::value, 
                          bool = isComplex<T>::value>
    struct myTypeTraits;
    
    template <typename T>
    struct myTypeTraits<T, true, false>
     { using type = T; };
    
    template <typename T>
    struct myTypeTraits<std::complex<T>, false, true>
     { using type = T; };
    
    template <typename T>
    class MyClass
     {
       public:  // public to check with the static_assert()
          using T0 = typename myTypeTraits<T>::type;
    
       private:
          T0 var1;
          T  var2;
     };
    
    int main ()
     {
       MyClass<int>                  mi; // compile
       MyClass<std::complex<float>>  mc; // compile
       // MyClass<std::string>          ms; // compilation error
    
       static_assert( std::is_same<int, decltype(mi)::T0>{}, "!" );
       static_assert( std::is_same<float, decltype(mc)::T0>{}, "!" );
     }