Я плохо знаком с C++. Я хотел бы знать, как опытные кодеры делают это.
что я имею:
set<int> s;
s.insert(1);
s.insert(2);
s.insert(3);
s.insert(4);
s.insert(5);
for(set<int>::iterator itr = s.begin(); itr != s.end(); ++itr){
if (!(*itr % 2))
s.erase(itr);
}
и конечно, это не работает. потому что itr увеличен после того, как он будет стерт. это означает, что Itr должен указать на начинание набора каждый раз после того, как я стираю элемент из набора?
for(set<int>::iterator itr = s.begin(); itr != s.end(); ){
if (!(*itr % 2))
s.erase(itr++);
else ++itr;
}
Эффективным STL Скотт Майерс
Стирание элемента из STD :: SET только недействителен только иверенными итераторами, указывающими на этот элемент.
Получите итератор к следующему элементу перед стиранием целевого элемента.
Вам не нужно возвращаться к началу. Set :: Erase
только недействительные итераторы, которые относятся к удалению элемента, поэтому вам просто нужно копировать итератор и приращение перед стиранием:
for(set<int>::iterator itr = s.begin(); itr != s.end();)
{
set<int>::iterator here = itr++;
if (!(*here % 2))
s.erase(here);
}
Лучший способ - использовать комбинацию remove_if и delete
s.erase(remove_if(s.begin(), s.end(), evenOddFunctor), s.end())
Это поможет. http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove
См. также эффективное STL от scott meyers
Edit
: Хотя мое решение неверно, я его не удаляю. Это может быть хорошим уроком для такого человека, как я, который не знает о мутируемых/перемещаемых итераторах