Ответ 1
for(set<int>::iterator itr = s.begin(); itr != s.end(); ){
if (!(*itr % 2))
s.erase(itr++);
else ++itr;
}
эффективный STL от Scott Myers
Я новичок в С++. Я хотел бы знать, как это делают опытные кодеры.
что у меня:
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 от Scott Myers
Стирание элемента из 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 и erase
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
: Хотя мое решение неверно, я не удаляю его. Это может быть хорошим обучением для такого человека, как я, который не знает об изменяемых и неизменяемых итераторах.