Как перебрать набор STL и выборочно удалить элементы? - PullRequest
7 голосов
/ 16 июня 2010

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

for (std::set<Color>::iterator i = myColorContainer.begin();
            i!=myColorContainer.end();
            ++i)
{
    if ( *i  == Yellow)
    {
        DoSomeProccessing( *i );
        myColorContainer.erase(i);
    }
}

Ответы [ 3 ]

7 голосов
/ 16 июня 2010

Попробуйте:

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++;
     }
}
6 голосов
/ 17 июня 2010

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

std::set<Color>::iterator it = myColorContainer.find(Yellow);
if (it != it.myColorContainer.end()){
  DoSomeProcessing(*it);
  myColorContainer.erase(it);
}
2 голосов
/ 17 июня 2010
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, что итераторы на вставленных элементах никогда не становятся недействительными, если элемент не удален.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...