Std:: find в устаревшем массиве

Как я могу провести std::find в унаследованном массиве , не создавая новый std::vector/std::array из существующего старого массива?

например:

int ar[N];

if ( std::find(ar, ar + N, value) != &ar[N] ){ /**/ }

Является ли &ar[N] допустимым значением для проверки ситуации, когда ничего не найдено? Могу ли я быть уверенным, что я прав, используя &ar[N] как аналог std::vector::end()?

Ответ 1

Если вы используете С++ 11, вы можете использовать:

int arr[N];
if (std::end(arr) == std::find(std::begin(arr), std::end(arr), value))
{
    // ...
}

Для С++ 98 вы можете использовать:

int arr[N];
int *begin = arr;
int *end = begin + N;

if (end == std::find(begin, end, value))
{
    // ...
}

Ответ 2

Ваша общая идея хорошая. Но ar[N] не "зарезервирован" для вас. Разделение выделенной переменной приведет к поведению undefined. Вы хотите сравнить результат std::find с ar + N, который не требует разыменования.

Ответ 3

Is & ar [N] допустимое значение для проверки ситуации, когда ничего не найдено?

Вы можете использовать ar+N вместо &ar[N], потому что ar +N безопасен, но &ar[N] попадает в область поведения undefined (на самом деле есть долгая дискуссия).

Семантически говоря, второй аргумент на самом деле конец диапазона, поэтому все, что вы передаете в качестве второго аргумента, возвращается, когда ничего не найдено в диапазоне. В вашем случае ar + N - второй аргумент, который также указывает конец диапазона. Поэтому вы можете написать это:

if ( std::find(ar, ar + N, value) != (ar + N) )
{ 
       //value found
}

Ответ 4

Нет, ar[N] разделяет один элемент после конца массива, поэтому он является незаконным.

Помните, что ar[N] эквивалентно *(ar + N) - поэтому он явно является разыменованием.

Перейдите с ar + N. Это законно иметь указатель 1 после окончания массива, он незаконно разыменовывает его.