Как выполнить итерации по набору STL и выборочно удалить элементы?

Следующий код не работает правильно. Как это должно быть сделано правильно?

for (std::set<Color>::iterator i = myColorContainer.begin();
            i!=myColorContainer.end();
            ++i)
{
    if ( *i  == Yellow)
    {
        DoSomeProccessing( *i );
        myColorContainer.erase(i);
    }
}
7
задан zr. 17 June 2010 в 07:43
поделиться

3 ответа

Вам не нужен цикл, поскольку вы имеете дело с набором.

std::set<Color>::iterator it = myColorContainer.find(Yellow);
if (it != it.myColorContainer.end()){
  DoSomeProcessing(*it);
  myColorContainer.erase(it);
}
6
ответ дан 6 December 2019 в 14:00
поделиться

Попробуйте:

for(std::set<Color>::iterator it = myColorContainer.begin(); 
    it != myColorContainer.end();) { // note missing it++
     if( (*it) == Yellow ) {
        DoSomeProcessing(*it);
        myColorContainer.erase(it++); // post increment (original sent to erase)
     }
     else {
       ++it; // more efficient than it++;
     }
}
7
ответ дан 6 December 2019 в 14:00
поделиться
for (std::set<Color>::iterator i = myColorContainer.begin();
            i!=myColorContainer.end(); /* No i++ */)
{
    if ( *i  == Yellow)
    {
        DoSomeProccessing( *i );
        std::set<Color>::iterator tmp = i;
        ++i;
        myColorContainer.erase(tmp);
    }
    else {
        ++i;
    }
}

После перехода к следующему сообщению с помощью ++i оно гарантированно будет валидным - свойство std::set, что итераторы на вставленных элементах никогда не аннулируются, пока элемент не будет не будет удален.

Так что теперь можно смело стирать предыдущую запись.

2
ответ дан 6 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: