2012-01-04 9 views
0

私はstd::listから要素を消去して、このリストに戻って指すようにしたいが、私はそれをこのようen要素を消去した後にstd :: listに正しく戻る方法(double for loop)?

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++); 
     } 
    } 

} 

を行うとき、私は持って、未処理の例外:iterator is unincrementable

+0

[可能重複](http://stackoverflow.com/q/596162/624900) – jterrace

+0

条件が対称であるならば、あなたはで内側のループを開始することができます'jt = it;' –

答えて

4

私は問題があると考えているのものいくつかのケース(要素を削除するもの)では、イテレータを二重に増やしています。あなたのforループは次のようになります。

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

しかし、その中にあなたは、このような何かをやっている:だから

jt = l.erase(jt); 

をする場合は、あなたが消去を行うことを起これば、あなたはそれを消去しで同じ時間に、イテレータを次の要素に設定します...しかし、あなたはまた、それをjt++でインクリメントします!

このフォームファクタにフィットするように、わずかにループのために再書き込みされ、これを固定する簡単な方法:

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

ので、あなたは、どちらか一方の増分、決して両方を行っています。

+0

それを避けるために私は何ができますか? – Patryk

+0

@Patryk:アップデートを参照してください。完全な答えを入力しているうちに、私はそこで基本を素早く取得しようとしていました:-)。 –

0

リストから要素を消去すると、その要素を指すイテレータは無効になりますが、他のイテレータは無効になります。だから、消去前の増分を実行する必要があります。

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'はイテレータを次の要素(または' end() ')に返します。 –

関連する問題