2013-01-13 36 views
9

我想爲每個循環使用新的C++ 11來迭代列表中的所有元素並擦除某些元素。例如是否有可能在每個循環中清除C++ 11中std :: list的元素

std::list<int> myList; 
myList.push_back(1); 
myList.push_back(13); 
myList.push_back(9); 
myList.push_back(4); 

for(int element : myList) { 
    if(element > 5) { 
     //Do something with the element 

     //erase the element 
    }else{ 
     //Do something else with the element 
    } 
} 

是否有可能做到這一點使用每個循環或者我得回去了迭代器來實現這一目標?

+3

爲什麼不能使用remove_if/erase? –

+3

或者只是'list :: remove_if',不需要迭代器。 –

+0

@KarthikT和@BenjaminLindley:對不起,我沒有提到我的問題。我想用滿足條件的元素和其他所有元素來做一些事情。我可能會把它放到'list :: remove_if'使用的Predicate函數中,但我覺得這不是很好。 – Haatschii

回答

6

你應該能夠只是這樣做

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

或者乾脆(禮貌本傑明·林德利)

myList.remove_if(
    [](int& element) 
    { 
     return element > 5; 
    } 
    ); 
+2

移位元素對列表來說相當低效 –

+0

hm,很好的編輯:)但是等等......'std :: erase'?你有沒有試過*編譯*這個? –

+2

@ Cheersandhth.-Alf我相信你錯了,刪除和插入爲O(1)爲std :: list。順序容器會發生移位,如std :: vector。 –

0

不,我不這麼認爲。見this SO answer:

不,你不能。基於範圍的用於當您需要訪問容器的每個 元素一次。

您應該使用正常的循環或它的一個表兄弟,如果你需要 修改的容器,當您去,訪問一個元素超過 一次,或者通過 容器在非線性的形式,否則迭代。

5

不能擦除標準集裝箱的元素在範圍爲基礎的循環在該容器 - 循環本身有一個迭代器,你當前訪問的元素,並刪除它會是無效迭代器之前循環增加它。

範圍爲基礎的標準的6.5.4被定義爲等同於(略簡體):

for (auto __begin=begin-expr, __end=end-expr; __begin != __end; ++__begin) { 
    for-range-declaration = *__begin; 
    statement 
} 

begin-exprend-expr有自己冗長的定義,但在你的例子他們myList.begin()和分別爲myList.end()

相關問題