模板类型推导 [英] Template type derivation

查看:105
本文介绍了模板类型推导的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用模板来实现一个类,例如 MyClass。

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

template<class T>
class MyClass
{
public:


          T var1;
          T1 var2;
        };

有两个成员变量var1和var2。如果类模板参数 T是基本类型(例如:float,double或long double),则变量var1和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.

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

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

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

如何在C ++ 11中实现?

How to implement it in C++11?

推荐答案

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

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; };

MyClass 成为

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

   T0 var1;
   T  var2;
 };

如果要确保 T 是基本类型(或者您是说算术吗?),要复杂一些。

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

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

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
 { };

接下来用声明修改 myTypeTraits (否通用定义)和两个默认布尔值

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; };

MyClass 类保持相等,但现在给出如果尝试使用 std :: string 实例化它,则会出现错误。

The MyClass class remain equals but now give an error if you try to instantiate it with (by example) a 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>{}, "!" );
 }

这篇关于模板类型推导的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆