c ++模板专业化中T []的类型是什么

时间:2013-05-21 12:06:32

标签: c++ c++11 typetraits

我对std::remove_extent(visual studio 11)

的实施有疑问
    template<class _Ty>
        struct remove_extent
        {
        typedef _Ty type;
        };

    template<class _Ty, unsigned int _Ix>
        struct remove_extent<_Ty[_Ix]>
        {
        typedef _Ty type;
        };

    template<class _Ty>
        struct remove_extent<_Ty[]> //what for?
        {
        typedef _Ty type;
        };

我刚试过这个:std::cout << typeid(int[]).name() << '\n';

,输出为:int [0],因此我假设_Ty[]代表_Ty[0]

但是专门针对_T[0]的目的是什么,我认为第二个案例已经解决了这个问题。

另外,我真的怀疑如果T [0]是有效类型,如果是,那么你在哪种情况下使用它?

2 个答案:

答案 0 :(得分:5)

T[]是一个未知大小的数组;不完整的类型,不同于任何大小的数组类型。似乎您的编译器有效但有点混乱,使用其他无效的T[0]作为该类型的字符串表示。

因此需要这种专业化,因为大小数组的部分专业化不会涵盖它。

  

如果是这样,在哪种情况下你会使用它?

您不会使用零大小的数组,因为那不是有效类型。

您可以在不同的地方使用不完整的类型(包括未知大小的数组),例如变量声明。例如:

extern int array[];                           // declaration with incomplete type
std::remove_extent<decltype(array)>::type x;  // OK, gives "int"
array[3] = 42;                                // OK, array decays to pointer

template <size_t N> size_t size(int (&a)[N]) {return N;}
std::cout << size(array) << "\n";             // Error, needs complete type

// somewhere else
int array[17];                                // definition with complete type
std::cout << size(array) << "\n";             // OK, size is known

答案 1 :(得分:1)

  

,输出为:int [0],因此我假设_Ty[]代表_Ty[0]

不,这与Mike Seymour的回答说的不一样。如果编译器的type_info名称相同,那么它看起来就像是一个问题。

  

另外,我真的怀疑如果T [0]是有效类型,如果是,那么你在哪种情况下使用它?

有些编译器允许它作为扩展,所以在这样的编译器上就可以了:

typedef int empty_array[0];   // typedef for int[0]
int* p = new empty_array;