2015-07-09 86 views
4

我只是想刪除指定的元素,在基於範圍的循環:如何從基於範圍的循環中刪除矢量?

vector<int> vec = { 3, 4, 5, 6, 7, 8 }; 
for (auto & i:vec) 
{ 
    if (i>5) 
    vec.erase(&i); 
} 

有什麼不對?

+2

那麼它不會編譯,讓我們開始在那裏! – Alejandro

+0

@alejandro好吧!你告訴我一種方法,使其編譯:) –

+0

可能重複的[從向量中刪除項目,而在c + + 11範圍循環?](http://stackoverflow.com/questions/10360461/removing-item-from -vector-while-in-c11-range-for-loop) – manlio

回答

3

您不能通過std::vector上的值擦除元素,並且由於基於範圍的循環直接暴露了您的代碼無意義的值(vec.erase(&i))。

主要問題是std::vector在擦除元素時會使其迭代器無效。

如此以來,基於範圍的環路基本上是作爲

auto begin = vec.begin(); 
auto end = vec.end() 
for (auto it = begin; it != end; ++it) { 
    .. 
} 

實現然後擦除值將無效it並打破連續的迭代。

如果你真的想刪除一個元素,而迭代你必須採取正確更新迭代器的護理:

for (auto it = vec.begin(); it != vec.end(); /* NOTHING */) 
{ 
    if ((*it) > 5) 
    it = vec.erase(it); 
    else 
    ++it; 
} 
8

從您正在迭代的矢量中移除元素通常是一個壞主意。在你的情況你最有可能跳過將使用std::remove_if它的7更好的方法:

vec.erase(std::remove_if(vec.begin(), vec.end(), 
          [](const int& i){ return i > 5; }), 
      vec.end()); 

std::remove轉變,應清除容器末端的元素,並返回一個迭代器首先是這些元素。那麼你只需要擦除那些元素直到最後。

+2

我們現在有['std :: experimental :: erase_if'](http://en.cppreference.com/w/cpp/experimental/vector/erase_if )。 –

2

這很簡單:不使用基於範圍的循環。這些循環旨在作爲的簡明形式,依次遍歷容器中的所有如果你想更復雜的東西(如刪除或一般訪問迭代器),做了明確的方法:

for (auto it = begin(vec); it != end(vec);) { 
    if (*it > 5) 
    it = vec.erase(it); 
    else 
    ++it; 
} 
+0

謝謝!我明白了你的觀點。 –