2012-01-04 1 views
0

Je veux effacer un élément de la std::list et pointera alors à cette liste, mais quand je le fais de cette façonComment retourner correctement à std :: list après avoir effacé un élément (double pour la boucle)?

for(std::list<CvRect>::iterator it = listOfCvRects.begin(); it != listOfCvRects.end(); it++) 
{ 
    for(std::list<CvRect>::iterator jt = listOfCvRects.begin(); jt != listOfCvRects.end(); jt++) 
    { 
     if(it == jt) 
     { continue;} 

     if((jt->x) > (it->x) //.. more conditions...) 
     { 
      jt = listOfCvRects.erase(jt); 
      //OR 
      //listOfCvRects.erase(jt++); 
     } 
    } 

} 

Je GOT et exception non gérée: iterator is unincrementable

+0

[double possible] (http://stackoverflow.com/q/596162/624900) – jterrace

+0

Si la condition est symétrique, vous pouvez démarrer la boucle interne à 'jt = ça,'. –

Répondre

4

je crois que le problème est que dans Dans certains cas (ceux où vous supprimez un élément), vous doublez l'itérateur. Votre boucle ressemble à ceci:

for(std::list<T>::iterator jt = l.begin(); jt != l.end(); jt++) { 
    .... 
} 

Mais à l'intérieur de celui-ci que vous faites quelque chose comme ceci:

jt = l.erase(jt); 

Donc, si le cas se produit que vous faites l'effacement, vous l'effacer et à la en même temps, réglez l'itérateur à l'élément suivant ... Mais, vous l'incrémentez aussi avec le jt++!

L'approche simple de la fixation de c'est récrire la boucle légèrement pour adapter ce facteur de forme:

for(std::list<T>::iterator it = l.begin(); it != l.end();) { // notice no increment! 
    // ... 
    if(cond) { 
     it = l.erase(it); 
    } else { 
     ++it; 
    } 
} 

donc vous font une ou l'autre des incréments, mais jamais les deux.

+0

Alors, que puis-je faire pour l'éviter? – Patryk

+0

@Patryk: voir mise à jour, j'essayais d'obtenir les bases rapidement là-bas pendant que je tapais la réponse complète :-). –

0

L'effacement d'un élément d'une liste invalide les itérateurs qui pointent sur cet élément, mais pas les autres itérateurs. Donc, vous devez faire l'incrément avant l'effacement:

for(std::list<CvRect>::iterator it = listOfCvRects.begin(); it != listOfCvRects.end(); it++) { 
    std::list<CvRect>::iterator jt = listOfCvRects.begin(); 
    while (jt != listOfCvRects.end()) { 
     if(it == jt) continue; 
     if((jt->x) > (it->x) //.. more conditions...) { 
      listOfCvRects.erase(jt++); 
     } else { 
      jt++; 
     } 
    } 
} 
+0

'erase' renvoie un itérateur à l'élément suivant (ou' end() '). –

Questions connexes