Ответ 1
но я не могу обернуть голову вокруг синтаксиса. Особенно в части
T (&) [size]
...
Эта часть является ссылкой на массив. Существует "право-левое правило" для расшифровки любых C и С++ деклараций.
Поскольку шаблоны функций выводят типы аргументов шаблона из аргументов функции, которые предоставляет этот шаблон функции, выведите количество элементов и элементов массива и верните счет.
Функции не могут принимать типы массивов по значению, а только указателем или ссылкой. Ссылка используется, чтобы избежать неявного преобразования массива в указатель на его первый элемент (иначе, разложение массива):
void foo(int*);
int x[10];
int* p = x; // array decay
foo(x); // array decay again
Распад массива разрушает исходный тип массива и, следовательно, его размер теряется.
Обратите внимание, что поскольку это вызов функции в С++ 03, возвращаемое значение не является константой времени компиляции (т.е. возвращаемое значение не может использоваться как аргумент шаблона). В С++ 11 функция может быть помечена constexpr
, чтобы вернуть константу времени компиляции:
template<typename T, size_t size>
constexpr size_t siz(T(&)[size]) { return size; }
Чтобы получить элемент массива как константу времени компиляции в С++ 03, можно использовать несколько другую форму:
template<class T, size_t size>
char(&siz(T(&)[size]))[size]; // no definition required
int main()
{
int x[10];
cout << sizeof siz(x) << '\n';
double y[sizeof siz(x)]; // use as a compile time constant 10
}
В приведенном выше примере объявляется шаблон функции с тем же аргументом reference-to-a-array, но с типом возвращаемого значения char(&)[size]
(здесь можно оценить "правое правое правило" ). Обратите внимание, что вызов функции никогда не происходит во время выполнения, поэтому определение шаблона функции siz
не требуется. sizeof siz(x)
в основном говорит: "Каким будет размер возвращаемого значения, если siz(x)
были вызваны".
Старый способ C/С++ для получения количества элементов массива как постоянной времени компиляции:
#define SIZ(arr) (sizeof(arr) / sizeof(*(arr)))