Подтвердить что ты не робот

Как работает шаблон размера массива?

Я нашел этот фрагмент

template <typename T, size_t N>  
char (&ArraySizeHelper(T (&array)[N]))[N];  
#define arraysize(array) (sizeof(ArraySizeHelper(array))) 

в этой статье http://software.intel.com/en-us/articles/pvs-studio-vs-chromium/

Я видел другие шаблоны, чтобы сделать то же самое, как этот

Используйте шаблоны, чтобы получить размер и конечный адрес массива

и я это понимаю, но у меня возникли трудности с этим.

Любая помощь будет оценена.

4b9b3361

Ответ 1

Шаблон функции имеет имя ArraySizeHelper, для функции, которая принимает один аргумент, ссылку на T [N] и возвращает ссылку на char [N].

В качестве аргумента макрос передает ваш объект (допустим, он X obj[M]). Компилятор сообщает, что T == X и N == M. Таким образом, он объявляет функцию с типом возврата char (&)[M]. Затем макрос обертывает это возвращаемое значение с помощью sizeof, поэтому он действительно делает sizeof(char [M]), который равен M.

Если вы даете ему тип без массива (например, a T *), то вывод параметра шаблона не будет выполнен.

Как показано ниже @Alf, преимущество этой гибридной матрицы-макросистемы над альтернативным подходом только шаблона заключается в том, что это дает вам константу времени компиляции.

Ответ 2

Это не самый приятный способ сделать это, но так как вы спрашиваете: тип возврата функции шаблона ArraySizeHelper равен char[N], где аргумент функции является массивом (ссылкой на) размера N типа T. Вычисление аргумента шаблона создает этот шаблон с совпадающим числом N, поэтому sizeof(char[N]) - это просто N, что вы получаете.

Более приятная версия может быть написана следующим образом. (Вам нужно С++ 0x для constexpr; если вы его опустите, это не будет постоянным выражением.)

template <typename T, size_t N> constexpr size_t array_size(const T (&)[N]) { return N; }

Использование:

int x[20];
array_size(x); // == 20

Обновление: Если вы находитесь в С++ 0x, вот еще одно решение, которое дает constexpr, благодаря decltype:

#include <type_traits>

template <typename T> struct array_traits;
template <typename T, unsigned int N> struct array_traits<T[N]>
{
   static const unsigned int size = N;
   typedef std::decay<T>::type type;
};

// Usage:
int x[20];
array_traits<decltype(x)>::size; // == 20

Ответ 3

Этот блог в MSDN точно описывает, как он работает. Очень интересная история. Взгляните на это.