Итератор остается указывать на элемент, который он ранее сделал, и значение, на которое он указывает, не удаляется из памяти. Интересно, как это можно объяснить? Спасибо.
forward_list<int> Fwdl {46, 21, 88, 901, 404};
auto it = Fwdl.begin();
Fwdl.remove(46);
cout << "List : "; for(int& elem : Fwdl) cout << " " << elem; cout << endl;
//This prints "List : 21 88 901 404" as expected, but:
cout << "Iterator is alive! " << *it << endl;
//This still prints "Iterator is alive! 46"
N4431 — 23.3.5.5/15 операции со списком [list.ops] (подчеркните мой)
void remove(const T& value);
template <class Predicate> void remove_if(Predicate pred);
Эффекты: удаляет все элементы в списке, на которые ссылается итератор списка.
i
для которого выполняются следующие условия:*i == value, pred(*i) != false
, Делает недействительными только итераторы и ссылки на стертые элементы.
То, что у вас есть, является типичным проявлением неопределенного поведения, и вы не должны полагаться на такой код.
Вероятно, что-то похожее на это:
int* p = new int(42);
int* iterator = p;
delete p;
// may still display 42, since the memory may have not yet been reclaimed by the OS,
// but it is Undefined Behaviour
std::cout << *iterator;
Как сказано в одном из комментариев, поведение разыменованного недействительного итератора является неопределенным поведением. В вашем случае это, вероятно, все еще указывало на пространство в куче, где был элемент, и еще не было перезаписано чем-то другим. На другом компиляторе или на другом прогоне программы это могло бы привести к срыву или полному сбою программы.