从数组类型中查找元素的类型

时间:2017-09-07 14:18:24

标签: c++ arrays templates metaprogramming

假设我有一个类型T,它保证是一个数组(例如int[32])。如何从数组类型中获取元素的类型?

我找到了一种方法,但它涉及声明一个虚拟临时变量,我想避免:

#include <iostream>
#include <typeinfo>

using namespace std;

template <typename T>
string getArrayType() {
    // Is there a better way to do this?
    T dummy;
    return typeid(dummy[0]).name();
}

int main() {
    cout << getArrayType<int[1]>() << endl;     // i
    cout << getArrayType<float[1]>() << endl;   // f
}

4 个答案:

答案 0 :(得分:4)

您也可以使用std::remove_all_extents

return typeid(typename std::remove_all_extents<T>::type).name();

此状态的文档

  

如果T是某种类型X的多维数组,则提供的成员typedef type等于X,否则输入为T

因此它将删除数组类型以获取该数组中包含的基础类型

答案 1 :(得分:2)

std::remove_all_extents<T>::type

<type_traits>标题中找到。而且,如果您的标准库是C ++ 14 rdy

std::remove_all_extents_t<T>

答案 2 :(得分:2)

如果您不想创建不必要的变量,可以使用std::remove_extent。它将为您提供数组类型的元素类型。那看起来像是

template <typename T>
string getArrayType() {
    return typeid(typename std::remove_extent<T>::type).name();
}

答案 3 :(得分:2)

  

假设我有一个类型T,它保证是一个数组(例如int [32])。如何从数组类型中获取元素的类型?

如果你使用typeid().name(),就像在你的例子中一样,你得到的是类型的名称,而不是类型。

如果你想要类型,并使用它编译时间,并且你希望它声明变量,你可以按如下方式定义类型特征

template <typename>  
struct typeOfArray
 { };

template <typename T, std::size_t N> 
struct typeOfArray<T[N]>
 { using type = T; };

以下是完整的(但是c ++ 11)工作示例

#include <iostream>
#include <type_traits>

template <typename>  
struct typeOfArray
 { };

template <typename T, std::size_t N> 
struct typeOfArray<T[N]>
 { using type = T; };

int main ()
 {
   static_assert( std::is_same<int,
                 typename typeOfArray<int[1]>::type>::value, "!" );

   static_assert( std::is_same<float,
                 typename typeOfArray<float[1]>::type>::value, "!" );

   typename typeOfArray<int[1]>::type i { 42 };

   std::cout << i << std::endl;
 }

如果必须使用c ++ 98,则无法使用using,因此不能使用

using type = T;

你必须使用typedef

typedef T type;

以下是c ++ 98示例(也使用typeid().name()

#include <typeinfo>
#include <iostream>

template <typename>  
struct typeOfArray
 { };

template <typename T, std::size_t N> 
struct typeOfArray<T[N]>
 { typedef T type; };

int main ()
 {
   std::cout << typeid(typeOfArray<int[1]>::type).name() << std::endl;
   std::cout << typeid(typeOfArray<float[1]>::type).name() << std::endl;
 }