2016-11-23 52 views
0

我知道擦除會自動將迭代器向前移動,所以當刪除多次出現時,我需要避免這種情況,以便我可以比較連續的元素。這就是爲什麼我通常做的:C++ 11:從矢量中刪除多個事件。最佳做法是什麼?

auto i = vect.begin(); 
while (i!=vect.end()) 
    if (*i==someValue) 
     vect.erase(i); 
    else 
     ++i; 

但我在想,如果我還可以用它做for循環,就像這樣:

for (auto i=vec.begin(); i!=vec.end(); ++i) 
    if (*i==someValue){ 
     vec.erase(i); 
     --i; 
} 

的--i部分看起來有點怪異,但它的工作原理。這是不好的做法嗎?錯誤的代碼?容易出錯?或者使用其中一種選擇恰到好處?

謝謝。

+1

很確定他們都不可靠。做到這一點:https://stackoverflow.com/questions/3938838/erasing-from-a-stdvector-while-doing-a-for-each – Ryan

+0

他們爲什麼不可靠?如果它是正確的,我寧願堅持我的選擇。然而,我不知道爲什麼它不正確(除了需要分配'i = vect.erase(i)'來防止迭代器失效。 –

回答

4

使用刪除和擦除成語:

auto new_end = std::remove(v.begin(), v.end(), some_value); 
v.erase(new_end, v.end()); 

即上面的代碼爲O(n)的複雜性,它可以在平行如果是從C++ 17沒有數據種族與

執行
template< class ExecutionPolicy, class ForwardIt, class T > 
ForwardIt remove(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, const T& value); 

parallelism TS

代碼有問題,因爲從vector.modifiers#3

影響:在失效迭代器和引用或擦除點之後

標準說,迭代器失效


然而,在現實中,大多數實現的保持迭代器指向舊節點,如果它是最後一個元素或下一個元素,現在它是end,那麼你的代碼的複雜度爲O(因爲它將循環n次,並多取n來換班。它也不能並行執行。

+0

由於某種原因,我的代碼錯了嗎? –

+0

@VanessaLarralde每個標準的措辭都是錯誤的 – Danh

+0

@Danh不僅僅是標準的措辭,因爲矢量存儲是保證連續性的,所以迭代器通常被實現爲向量存儲的簡單內存指針,如果元素刪除的結果是存儲縮小(並且因此,重新分配),所有現有的迭代器都會變成單純的懸掛指針 – Dmitry

相關問題