Я создал программу, чтобы попытаться попрактиковаться в семантике структуры данных списка.Я заметил странную разницу в следующих частях кода:
Первый код:
#include<iostream>
#include<list>
using namespace std;
int main() {
list<int> l;
int n = 100;
for(int i = 0; i < n; i++) {
l.push_back(i);
}
list<int>::iterator it = l.end();
it--;
for(; !l.empty(); it--) {
cout << "the size of l is " << (int) l.size() << endl;
l.erase(it);
}
}
Второй код:
#include<iostream>
#include<list>
using namespace std;
int main() {
list<int> l;
int n = 100;
for(int i = 0; i < n; i++) {
l.push_back(i);
}
list<int>::iterator it = l.end();
it--;
for(; !l.empty();) {
cout << "the size of l is " << (int) l.size() << endl;
l.erase(it--);
}
}
Цель обоих частей кодапросто - просто стереть все элементы в списке.
Единственная разница между ними - это место, где итератор списка уменьшается.В первом примере кода я использовал поток управления цикла for, чтобы уменьшить итератор.Во втором я использовал пост-декрементный оператор для уменьшения итератора.
Исходя из моего понимания, приведенные выше примеры кода должны быть эквивалентны, потому что я уменьшаю итератор сразу после удаленияэлемент из списка.Кроме того, согласно документам STL, только итератор для стертого элемента в списке становится недействительным.Поэтому не должно быть никакого неопределенного поведения.
Проблема в том, что второй пример кода работает, как и ожидалось, - он останавливается после удаления всех элементов в списке.Однако для первого образца размер списка может даже стать отрицательным ?!Когда я попытался увеличить начальное количество элементов в списке, первая программа зависала на полпути.
Может кто-нибудь любезно посоветовать мне, почему эти примеры кода ведут себя по-разному?