从数组的类型中查找元素的类型
Find the type of the elements from the type of the array
假设我有一个类型 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
}
std::remove_all_extents<T>::type
在 <type_traits>
header 中找到。而且,如果你的标准库是 C++14 rdy
std::remove_all_extents_t<T>
如果您不想创建不必要的变量,可以使用 std::remove_extent
。它会给你数组类型的元素类型。那看起来像
template <typename T>
string getArrayType() {
return typeid(typename std::remove_extent<T>::type).name();
}
您也可以使用 std::remove_all_extents
return typeid(typename std::remove_all_extents<T>::type).name();
此说明的文档
If T
is a multidimensional array of some type X
, provides the member typedef type
equal to X
, otherwise type is T
.
因此它将删除数组类型以获取该数组中包含的基础类型
Suppose I have a type T which is guaranteed to be an array (eg. int[32]). How do I get the type of the elements from the type of the array?
如果您使用 typeid().name()
,如您的示例,您将获得类型的 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;
}
假设我有一个类型 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
}
std::remove_all_extents<T>::type
在 <type_traits>
header 中找到。而且,如果你的标准库是 C++14 rdy
std::remove_all_extents_t<T>
如果您不想创建不必要的变量,可以使用 std::remove_extent
。它会给你数组类型的元素类型。那看起来像
template <typename T>
string getArrayType() {
return typeid(typename std::remove_extent<T>::type).name();
}
您也可以使用 std::remove_all_extents
return typeid(typename std::remove_all_extents<T>::type).name();
此说明的文档
If
T
is a multidimensional array of some typeX
, provides the member typedeftype
equal toX
, otherwise type isT
.
因此它将删除数组类型以获取该数组中包含的基础类型
Suppose I have a type T which is guaranteed to be an array (eg. int[32]). How do I get the type of the elements from the type of the array?
如果您使用 typeid().name()
,如您的示例,您将获得类型的 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;
}