2013-05-21 3 views
0

У меня есть вопрос о реализации std::remove_extent (Visual Studio 11)C++, что является типом T [] в специализации шаблона

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] является допустимым типом, если да, то в каком случае вы можете использовать это?

+1

'T [0]' не является допустимым типом, поэтому имя коверкая грамматику на вашей платформе повторно использовал свое имя динамического типа для представления 'T []'. – Potatoswatter

ответ

5

T[] - массив неизвестного размера; неполный тип, отличный от любого типа массива. Кажется, что ваш компилятор, правда, но несколько смутно, использует в противном случае как строковое представление типа.

Так что эта специализация необходима, поскольку она не будет покрыта частичной специализацией для массивов с размерами.

Если да, то в каком случае вы используете это?

Вы не использовали бы массив нулевого размера, так как это недопустимый тип.

Вы можете использовать неполные типы (включая массивы неизвестного размера) в разных местах, например объявления переменных. Например:

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 
+0

Спасибо за объяснение. Но я до сих пор не понимаю, что такое массив неизвестного размера? И как передать нестандартный массив этому шаблону? похоже, что std :: remove_extent попадает в базовый регистр. – Frahm

+0

@Frahm: Я привел несколько примеров того, что вы можете сделать с массивом неизвестного размера. –

+0

Спасибо за примеры. – Frahm

1

и выходе: int [0], поэтому я полагаю, _Ty[] стенды для _Ty[0].

Нет, это не то же самое, как говорит Майк Сеймур. Это похоже на проблему с именем вашего компилятора type_info, если он говорит, что это то же самое.

Кроме того, я действительно сомневаюсь, что если T [0] является допустимым типом, если да, то в каком случае вы используете это?

Некоторые компиляторы позволяют это как расширение, так что это нормально на таких трансляторов:

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

Имя типа может быть любым ... Я удивлен, что 'name()' возвращает такую ​​удобочитаемую строку на любой платформе. Это не проблема с именем, это проблема с чтением слишком много в нем, помимо того, что это уникальный NTBS для каждого типа. – Potatoswatter

+0

Хорошая мысль об этом должна быть единственной NTBS, и если платформа не поддерживает расширение длины нулевой длины, то строка '' T [0] "' не берется и может использоваться для 'T [ ] ' –

 Смежные вопросы

  • Нет связанных вопросов^_^