Я должен сделать тривиальную итерацию всех элементов в std :: map, от первого до последнего. На каждом элементе я должен выполнить операцию. Предположим, что карта содержит следующие пары:
map<string,string> farm={
{"one","puppy"},
{"two","kitty"},
{"three","sheepy"}
}
Бит кода, который выполняет итерацию, следующий:
for(map<string,string>::iterator beast; beast!=farm.end(); ++beast)
{
feed(*beast);
}
Теперь удивительно, что приведенный выше код работает для первого элемента (puppy
подается), но итератор не может перейти к следующим элементам. Отладчик показывает, что ++beast
никогда не возвращается (кажется, что он рекурсивно разветвляется на своем левом листе навсегда).
Кажется, проблема здесь в том, что beast
никогда не назначается farm.begin()
и как таковой он не может перейти к следующему элементу (см. первый элемент для).
Итак, вот мои вопросы:
Это нормально, что конструктор по умолчанию итератора карты автоматически позиционирует объект так, чтобы он указывал на map.begin()
элемент?
Если это обычная практика, то почему первый действительный элемент
вернулся (он мог быть возвращен map.end()
например) ?
Как мог operator++
можно спокойно потерпеть неудачу в бесконечном цикле? Не лучше было бы вернуться с кодом ошибки (мы отключили
исключения) или открыто как-то провалиться?
Интересно, допускает ли стандарт такого рода поведение или это выбор реализации.
Предположения: Я не использую C ++ 11, я использую компилятор Green Hills v2016 с отключенной поддержкой исполнения
РЕДАКТИРОВАТЬ:
Я пытаюсь понять, почему я получаю правильное значение и тихий сбой, поскольку в других потоках люди предполагают, что построенный по умолчанию итератор назначен map.end()
, Стандарт дает руководство по этому вопросу?
Это нормально, что конструктор по умолчанию для итератора карты
автоматически позиционирует объект так, чтобы он указывал на map.begin ()
элемент?
Нет, вы должны правильно его инициализировать:
for(map<string,string>::iterator beast = farm.begin(); beast!=farm.end(); ++beast)
Кстати, компилятор не может знать, что вы хотите map<string,string>::iterator beast
быть итератором для farm
Конечно, вам нужно получить итератор из контейнера, а не просто создать итератор и предположить, что он указывает на нужный вам контейнер.
Других решений пока нет …