c++ - 模板类型推导

标签 c++ c++11 templates template-specialization template-argument-deduction

我需要实现一个类,比如使用模板的“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中实现?

最佳答案

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

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 是一个基本类型(或者你的意思是算术?),有点复杂。

一种可能的方法是定义一个类型特征来说明(truefalse)如果类型是 std::complex

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

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

接下来用声明(无通用定义)和两个默认 bool 值修改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; };

MyClass 类保持不变,但如果您尝试使用(通过示例)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>{}, "!" );
 }

关于c++ - 模板类型推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47334675/

相关文章:

c++ - 默认移动构造函数

c++ - 是否可以在编译时计算数字阶乘,但没有枚举

c++ - 为什么 Core i5-6600 在非方矩阵乘法上比 Core i9-9960X 更快?

javascript - -nan 在 C++ 中是什么意思?为什么 pow(-4, -2.1) 返回 -nan?

c++ - 线程中的异常

c++ - 在以固定大小为模板的不同大小的缓冲区之间复制

python - getopts Values 类和 Template.Substitute 不(立即)一起工作

c++ - 如何在C++中将小数点后两位数字78.125打印为78.13

unix 中的 c++ 编译器版本

c++ - 无参数的 std::thread 构造函数