2014-01-14 23 views
1

這段代碼不應該進入無限循環嗎?不應該從stl :: list像這樣去掉無限循環?

list<int>val; 
    val.push_back(0); 
    list<int>::iterator iter,iterEnd; 
    iter = val.begin(); 
    int i; 
    for (; iter != val.end();) 
    { 
     i = *iter; 
     if(i==0) 
     { 
      val.erase(iter++); 
     } 
     else iter++; 
    } 

因爲它有做擦除,然後遞增迭代之後只有一個值,不應迭代超過值val.end(),然後陷入無限循環?但是當我運行它時,它運行得很好!任何人都可以解釋嗎?謝謝。

+0

'目錄:: erase'並不能否定任何其他迭代器除了一個被刪除。 –

回答

4

在您的示例iter之前std::list::erase通話和

引用和迭代器擦除元素無效實際遞增。其他引用和迭代器不受影響。 (cppreference)

所以當發生刪除時,iter已經指向下一個有效元素。

僞相當於lst.erase(iter++);

temp = iter 
iter += 1 
lst.erase(temp) 
+0

那麼它如何刪除第一個值?由於它在開始時指向第一個值,所以在擦除之前我們再次增加它。當發生擦除時,迭代器是否應該指向第二個值(如果有的話)並擦除第二個值? – Tahlil

+1

迭代器的後增量在增量之前返回迭代器,這就是爲什麼擦除得到正確的元素。 – Erbureth

+0

@kalkin查看僞代碼 – Erbureth

1

做擦除,然後遞增迭代器

這就是你錯了。它首先遞增迭代器(因爲函數參數在調用函數之前被求值),然後擦除迭代器的舊值。

因爲erase使用後遞增(而不是在單獨的步驟中遞增,因此erase使迭代器無效到擦除的元素)。通過首先遞增,iter本身不會失效,只有預增加返回的副本。

+0

s/pre-increment/post-increment/ – Erbureth