Попробуйте вместо этого:
for (it=sList.begin(); it != sList.end(); it++)
{
for (it2=sList.end()-1; it2 != it+1; it2--)
{
if ((*it) == (*it2))
{
it = sList.erase(it, it2)-1;
break;
}
}
}
Эта новая версия позволяет избежать двух ошибок в исходной версии кода. Во-первых, код теперь правильно обрабатывает краевые условия внутреннего цикла for. В исходном коде цикл for позволил it2
подняться до sList.end()-1
, но затем следующая строка увеличила его до sList.end()
на последней итерации. Следующая строка затем разыменовывает этот (недопустимый) итератор, который находится на единицу после последнего значения списка (потому что это то, что возвращает end
, это не итератор до последнего значения списка).
Во-вторых, вызов erase
делает недействительными любые итераторы, указывающие на любое из удаленных значений (которые в этом случае будут включать любые итераторы от it
до it2-1
). Начав с конца списка и продвигаясь вперед, нам больше не нужно продолжать итерации, когда мы находим значение, и можем break
из внутреннего цикла, как только мы его найдем. erase
возвращает итератор для следующего элемента в списке после удаленных элементов (который будет следующим элементом, который мы хотим использовать для it
). Но поскольку цикл for увеличивает it
, мы вычитаем 1 из того, что возвращает erase
, так что it
указывает на правый элемент после его увеличения в начале следующей итерации цикла. (Обратите внимание, что в случае, когда it
указывает на первый элемент, мы фактически временно устанавливаем его так, чтобы он указывал на элемент перед началом списка; однако это только временно, и мы не разыменовываем итератор, когда он указывает вне список).
Обратите внимание, что это сохраняет исходное поведение кода для случая 0 2 3 4 5 1 6 7 8 0 9 10 11 1
. Вы явно не указали, в каком порядке должны выполняться удаления (если элементы между 0
будут удалены первыми, или элементы между 1
, или нам нужно добавить дополнительную логику, чтобы фактически стереть весь диапазон за исключением первых 0
и 1
?), но этот код ведет себя как оригинал и стирает числа между 0
и игнорирует тот факт, что впоследствии 9 10 11
был оригинальным между совпадениями 1
s.