Получение указателя на конец массива

Я использую следующий шаблон для получения указателя, указывающего после последнего элемента массива:

template <typename T, size_t n>
T* end_of(T (&array)[n])
{
    return array + n;
}

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

int test[] = {11, 19, 5, 17, 7, 3, 13, 2};
std::sort(test, end_of(test));

Ответ 1

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

template <typename T, size_t N> char (&array(T(&)[N]))[N];

int main()
{
  int myArray[10];

  std::cout << sizeof array(myArray) << std::endl;

  return 0;
}

Он работает, создавая массив типа char, который представляет собой то же количество элементов, что и данный массив. sizeof всегда возвращает размер в количестве символов.

Ответ 2

Единственная проблема, которую я вижу, заключается в том, что если вы когда-либо не знаете длину во время компиляции, ваш шаблон не будет знать, что добавить туда. Поэтому вы должны сказать test+x или что-то в любом случае, и теперь у вас есть два разных способа сделать то же самое.

Лично я бы просто использовал vector<int> и, таким образом, имел end(), уже определенный для меня. Если вам нужен массив, он доступен как &v[0].

Ответ 3

Вам также нужна версия const. Однако, насколько мне известно, реальных проблем с этим подходом нет, я вижу, что это обычно используется.