Подтвердить что ты не робот

Поведение std:: list: begin(), когда список пуст

Получают ли следующие результаты в терминах стандарта С++?

std::list<int> myList;
std::list<int>::iterator myIter = myList.begin();    // any issues?
myList.push_back( 123 );
myIter++;                                  // will myIter point to the 123 I pushed?

Я могу проверить это на компиляторе, который я использую... но я бы хотел получить более окончательный ответ.

4b9b3361

Ответ 1

Все стандартные итераторы и типы контейнеров ведут себя одинаково в этом отношении:

§23.2.1 [container.requirements.general] p6

begin() возвращает итератор, ссылаясь на первый элемент в контейнере. end() возвращает итератор, который является значением конца для контейнера. Если контейнер пуст, то begin() == end();

И таблица 107 в §24.2.3 [input.iterators] требует, чтобы в качестве предварительного условия для ++it, it было разыменовано, что не относится к итераторам прошедшего конца (т.е. что вы получаете от end()), как таковой вы находитесь в страшном домене поведения undefined.

Ответ 2

std::list<int> myList;
std::list<int> myIter = myList.begin();

Итератор имеет такое же значение, как если бы вы инициализировали его с помощью myList.end(). Итератор инициализируется положением "взад-вперед". Даже после того, как вы вставляете элемент в список, итератор все еще указывает один на один конец. Если вы увеличиваете его, вы вызываете поведение undefined.

UPDATE:

Например, если вы скомпилируете свой фрагмент с GCC с -D_GLIBCXX_DEBUG, результирующий исполняемый файл будет прерван:

/usr/include/c++/4.6/debug/safe_iterator.h:236:error: attempt to increment 
    a past-the-end iterator.

Objects involved in the operation:
iterator "this" @ 0x0x7fffc9548fb0 {
type = N11__gnu_debug14_Safe_iteratorINSt9__cxx199814_List_iteratorIiEENSt7__debug4listIiSaIiEEEEE (mutable iterator);
  state = past-the-end;
  references sequence with type `NSt7__debug4listIiSaIiEEE' @ 0x0x7fffc9548fb0
}
zsh: abort (core dumped)  ./listiter