2013-01-13 9 views
9

Chcę użyć nowego C++ 11 dla każdej pętli do iteracji nad wszystkimi elementami listy i wymazywania elementów certyfikatów. Na przykład:Czy jest możliwe, aby usunąć elementy std :: list w C++ 11 dla każdej pętli

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 
    } 
} 

Czy można to zrobić za pomocą każdej pętli lub czy muszę powrócić do iteratorów, aby to osiągnąć?

+3

dlaczego nie możesz użyć remove_if/erase? –

+3

Lub po prostu 'list :: remove_if', nie potrzebne iteratory. –

+0

@KarthikT i @BenjaminLindley: Przepraszam, nie wspominałem o moim pytaniu. Chcę zrobić coś z elementami, które spełniają warunek, a także z wszystkimi innymi. Prawdopodobnie mógłbym umieścić to w funkcji predykatu używanej przez 'list :: remove_if', ale uważam, że nie jest to zbyt miłe. – Haatschii

Odpowiedz

6

Powinieneś być w stanie po prostu zrobić to

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

lub po prostu (dzięki uprzejmości Benjamin Lindley)

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

Zmiana elementów jest dość nieefektywna dla listy –

+0

hm, dobra edycja :) ale czekaj ... 'std :: erase'? czy próbowałeś * skompilować * to? –

+2

@ Cheersandhth.-Alf Wierzę, że się mylisz, usunięcie i wstawienie to O (1) dla std :: list. Przesunięcie nastąpi w przypadku pojemników sekwencyjnych, takich jak std :: vector. –

0

Nie, nie sądzę. Patrz: this SO answer:

Nie, nie możesz. Zasięg bazuje na tym, że musisz jednorazowo uzyskać dostęp do każdego elementu kontenera.

należy użyć normalnej pętli for lub jeden z nich znajduje się kuzynów jeśli trzeba zmodyfikować pojemnik jak iść, dostęp element więcej niż raz, lub w inny sposób iteracyjne w nieliniowy przez pojemnik .

5

Nie można usuwać elementów standardowych kontenerów w pętli opartej na odległościach nad tym kontenerem - sama pętla ma iterator do elementu, który obecnie odwiedzasz, a jego usunięcie spowoduje unieważnienie tego iteratora przed pętlą zwiększa ją.

Zakres oparte o zdefiniowane jest w 6.5.4 normy za równoważne (nieco uproszczonej):

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

begin-expr i end-expr mają własne długi definicję, ale w swoim przykładem są myList.begin() i myList.end() odpowiednio.

Powiązane problemy