Как делает этот “размер массива”, обрабатывают функциональную работу по шаблону? [дубликат]

47
задан Community 23 May 2017 в 12:10
поделиться

1 ответ

Сначала давайте проанализируем параметр T (&) [size] . Прочтите объявления изнутри наружу, справа налево, сначала группа скобок: это безымянный параметр, который является ссылкой на массив размера size типа T .

То есть он принимает ссылку на любой массив, где тип и размер массива являются параметрами шаблона.

Если мы назовем это так:

int a[10];
GetArrLength(a);

Компилятор попытается вывести параметры шаблона. Чтобы тип параметра соответствовал тому, что вы передаете, T должен быть int , а размер должен быть 10 (что делает параметр ссылкой на массив из 10). int s).

Затем вы возвращаете этот размер, давая вам количество элементов в массиве.


У этого кода есть две «проблемы».Во-первых, размеры не могут быть отрицательными, поэтому нет смысла использовать подписанный тип в качестве параметра шаблона и типа возвращаемого значения. Скорее следует использовать беззнаковый тип; лучше всего было бы std :: size_t :

template<typename T, std::size_t Size>
std::size_t GetArrLength(T(&)[Size]) { return size; }

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

template <std::size_t N>
struct type_of_size
{
    typedef char type[N];
};

template <typename T, std::size_t Size>
typename type_of_size<Size>::type& sizeof_array_helper(T(&)[Size]);

#define sizeof_array(pArray) sizeof(sizeof_array_helper(pArray))

Это используется как таковое:

int a[10];
const std::size_t n = sizeof_array(a); // constant-expression!

Это работает по трем причинам: первое - это та же идея, что и выше, что параметры шаблона будут заполнены, давая вам размер массива.

Вторая часть использует эту информацию для создания типа с определенным размером, отсюда и вспомогательный метод type_of_size . Эта часть не является строго необходимой, но я думаю, что она упрощает чтение кода. char [N] всегда имеет размер, равный N , поэтому мы можем злоупотребить этим, чтобы «сохранить» размер массива ... в размере ] введите сам!

Третья часть получает этот размер с помощью sizeof . На самом деле он ничего не оценивает, поэтому нам не нужно определение функции. Там просто написано: «Если бы вы сделали это ... размер был бы ...». И размер - это наш "сохраненный" размер в массиве char .

58
ответ дан 26 November 2019 в 19:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: