2011-03-21 65 views
2

that page,它說:有效性迭代器指向到刪除項目

這會使所有迭代器和位置 或後先元素 引用。

這是否意味着positionfirst迭代器在擦除後有效?

(顯然,我問,因爲我想一個for_each的循環過程中刪除的矢量一些項目。)

謝謝。

回答

2

根據http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#414positonfirst應被視爲無效 - 標準措辭不清楚,但作爲迭代器和引用一句話提到,並擦除的元素的引用,沒有任何意義,這是「取理所當然「,即擦除指向擦除元素的無效迭代器。我會避免取決於被刪除的迭代器是否有效 - 當您從一個元素中刪除begin()時,我不會理所當然地認爲迭代器突然等於end()

+1

」該標準特別指出:「在擦除點之後使所有迭代器和引用無效」。這已被提出爲缺陷。C++ 0x的N3242草案將此更改爲:「使迭代器和引用無效「 - Jerry Coffin – BenjaminB 2011-03-21 15:47:43

+0

@Jerry Coffin所以我明白了,這顯然是一個缺陷,然而, 然而,因爲沒有使迭代器無效的定義意味着它指向它先前所做的相同元素 如果元素已被刪除,這是不可能的。 – 2011-03-21 18:21:32

0

是的。但是他們不會提到erase()之前的元素,因爲那個元素已經被刪除了!

2

通常,如果您嘗試刪除多個來自vector的項目在循環中使用remove_if將爲您提供比在每個項目上使用erase更好的性能。考慮這個,而不是迭代 - 擦除。

但是,要回答你的問題,他們是有效的,但要小心增加迭代器再次測試end之前,因爲擦除可能使您的迭代器現在等於end。編輯:@埃裏克的答案表明它可能實際上不是有效的,但措辭不明確。

+0

性能尚未(但)是一個問題,我不夠熟悉stl編寫漂亮的代碼與算法。 – BenjaminB 2011-03-21 15:53:46

0

如果您刪除,而迭代,認爲這句法:

vector<int> items = ...; 

for(vector<int>::iterator it = items.begin() ; it != items.end() ; /*inline*/) 
{ 
    if(/* should erase*/) 
     it = items.erase(it); 
    else 
     ++it; 
} 

這工作,因爲erase()在當前操作後返回一個迭代到下一個元素。所以,如果你擦除了,它會「增加」,否則,你會像正常一樣增加它。正如其他人已經指出的那樣,這不是非常有效率(因爲現有的所有元素都被複制),並且有更好的方法。例如,正如Mark B所說,使用remove_if可能會更好。

+0

Thx的提示,我會做到這一點。 – BenjaminB 2011-03-21 15:49:39

0

這就是它說的,但它是錯誤的。根據標準, 他們是無效的(這是有道理的,因爲保持有效, 他們必須指向一個不再存在的元素)。 「

+1

其實沒有。該標準特別指出:「在擦除點之後使所有迭代器和引用*失效。」這已經成爲一個缺陷。 C++ 0x的N3242草案將其更改爲:「在擦除點處或之後使迭代器和引用*失效。」 – 2011-03-21 15:15:25

+0

非常有用的評論傑裏棺材。 – BenjaminB 2011-03-21 15:44:13