Действительность списка начала итератора после вставки - PullRequest
4 голосов
/ 29 января 2020

Рассмотрим следующую программу:

#include <list>
#include <cstdio>

int main() {
    std::list<int> l;
    std::list<int>::iterator it = l.begin();
    l.push_back(0);
    l.insert(it, 1);
    for(const int &i: l) {
        printf("%d", i);
    }
}

(http://cpp.sh/66giy)

Это печатает 01. Очень неожиданно. Если я изменю список на deque, он напечатает ожидаемый 10.

Это ошибка?

EDIT: поведение deque не имеет значения, итераторы для запросы отменяются push_back.

1 Ответ

1 голос
/ 11 февраля 2020

Я не могу уловить вашу проблему ... хорошо, давайте попробуем воспроизвести:

std::list<int> l;
std::list<int>::iterator it = l.begin();

На что указывает ваш итератор? До конца списка, поскольку список пуст!

§23.2.1 [container.requirements.general] p6

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

l.push_back(0);

Теперь список содержит один элемент. Ваш итератор действителен, так как список не сделал недействительным итератор и все еще указывает на конец списка.

l.insert(it, 1);

Теперь вы вставляете 1 перед итератором, который указывает на конец. Итак, ваш первый элемент - 0, а последний - 1.

Итак, ваш вывод 01, как и ожидалось.

Возможно, вы ожидаете, что begin() доставит фиксированный виртуальный запуск контейнера итератора просто неверен?

...