В соответствии с некоторыми документами STL, которые я нашел, вставка или удаление элементов в std:: list не делает недействительными итераторы. Это означает, что разрешено перебирать список (от begin()
до end()
), а затем добавлять элементы с помощью push_front.
Например, в следующем коде я инициализирую список с элементами a, b и c, затем перебираю его и выполняю push_front элементов. Результатом должен быть cbaabc, и именно это я получаю:
std::list<std::string> testList;
testList.push_back("a");
testList.push_back("b");
testList.push_back("c");
for (std::list<std::string>::iterator itList = testList.begin(); itList != testList.end(); ++itList)
testList.push_front(*itList);
for (std::list<std::string>::const_iterator itList = testList.begin(); itList != testList.end(); ++itList)
std::cout << *itList << std::endl;
Когда я использую обратные итераторы (цикл от rbegin()
до rend()
) и используйте push_back, я бы ожидал подобного поведения, то есть результата abccba. Однако я получаю другой результат:
std::list<std::string> testList;
testList.push_back("a");
testList.push_back("b");
testList.push_back("c");
for (std::list<std::string>::reverse_iterator itList = testList.rbegin(); itList != testList.rend(); ++itList)
testList.push_back(*itList);
for (std::list<std::string>::const_iterator itList = testList.begin(); itList != testList.end(); ++itList)
std::cout << *itList << std::endl;
Результат не abccba
, а abcccba
. В этом случае добавляется еще один c.
Похоже, что первый push_back также изменяет значение итератора, инициализированного с помощью rbegin(). После push_back он больше не указывает на третий элемент в списке (который ранее был последним), а на четвертый элемент (который теперь является последним).
Я тестировал это как с Visual Studio 2010, так и с GCC, и оба возвращали тот же результат.
Это ошибка? Или какое-то странное поведение обратных итераторов, о которых я не знаю?