Template type derivation

雨燕双飞 提交于 2019-12-14 03:08:01

问题


I need to implement a class, say 'MyClass' using templates.

template<class T>
class MyClass
{
public:


          T var1;
          T1 var2;
        };

There are two member variables var1 and var2. If the class template argument, 'T', is fundamental type (eg: float, double or long double), the types of both the variables var1 and var2 should be the same as the template argument. That is T1 = T in the above example.

But if the template argument is std::complex<T>, I would like to have

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

How to implement it in C++11?


回答1:


A possible solution could be define a simple type traits to extract the correct type

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

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

and MyClass become

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

   T0 var1;
   T  var2;
 };

If you want to be sure that T is a fundamental type (or do you mean arithmetic?), is a little more complicated.

A possible way is define a type traits to say (true or false) if a type is a std::complex

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

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

Next modify myTypeTraits with a declaration (no generic definition) and two default bool values

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

Next two specializations, the first one for fundamentals and the second one for complexes types

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

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

The MyClass class remain equals but now give an error if you try to instantiate it with (by example) a std::string.

The following is a full compiling example

#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>{}, "!" );
 }


来源:https://stackoverflow.com/questions/47334675/template-type-derivation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!