Re[3]: Как правильно определить ARRAYSIZE?
От: korzhik Россия  
Дата: 15.02.05 17:47
Оценка: 26 (5)
Здравствуйте, Аноним, Вы писали:

K>>template<class T, std::size_t N> 
K>>char(&lenghtOf(T(&)[N]))[N];

K>>#define lenghtOf(arr) sizeof(lenghtOf(arr))


А>упппс, где такие фокусы описываются, где про это можно почитать?

А>эт что-то из метапрограммирования, э?

читать про это в учебнике по C++
если надо могу объяснить что значит такая запись...
Итак:
template<class T, std::size_t N> 
char(&lenghtOf(T(&)[N]))[N];


T(&)[N] — это есть ссылка на массив, имя ссылки мы здесь убрали потому что оно нам не надо.
  char A[10];
  char(&arr_ref)[10] = A; // скобки здесь необходимы, 
  // потому что если их убрать, то получится массив ссылок, который не допустим

  char& ref_arr[10]; // error


далее, чтобы было понятнее, зададимся задачей написать функцию которая принимает ссылку на массим char'ов из 10 элементов
и её же возвращает.
Попробуем реализовать:
char(&)[10] ref2ref(char(&ref)[10])
{
  return ref;
}

Упс, вылезла ошибка!
Попробуем по другому:
char (& ref2ref(char(&ref)[10]) )[10]
{
  return ref;
}

Вот так всё нормально! Вот такой синтаксис.

Теперь посмотрим на нашу дурацкую, непонятную запись ещё раз:
template<class T, std::size_t N> 
char(&lenghtOf(T(&)[N]))[N];

теперь мы можем сказать что это!
Это — объявление шаблонной функции lenghtOf, которая принимает ссылку на массив элементов типа T размером N и возвращает ссылку на массив char'ов размером N. Так как это шаблонная функция то компилятор сделает вывод аргументов.
То есть если мы напишем
  int A[10];
  lenghtOf(A);

то компилятор сам додумается что вместо T надо подставить int, а вместо N подставить 10.
Также нам не надо определять тело функции, достаточно только нашего объявления, так как оператор sizeof интерисует только возвращаемый тип нашей функции, саму функцию он не вызывает.
Теперь осталось написать только макрос, для удобства:
#define lenghtOf(arr) sizeof(lenghtOf(arr))

ну здесь всё просто.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.