При работе с указателями указатели на один за концом имеют (в основном) определенное поведение:
int array[8];
int* x = array + 8; // Still considered pointing to part of array in expressions
Итераторы используют это, сравнивая указатель итератора с последним за концом.
Обратные итераторы делают то же самое, но с одним перед началом массива:
int array[8];
int* x = array - 1;
Разве это не неопределенное поведение? Содержат ли контейнеры дополнительный элемент и считают [1]
началом?