2013-01-13 12 views
9

Voglio usare il nuovo C++ 11 per ogni ciclo per scorrere tutti gli elementi di un elenco e cancellare elementi di determinati. Per esempioE 'possibile cancellare elementi di uno std :: list in un C++ 11 per ogni ciclo

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

E 'possibile farlo utilizzando la per ogni ciclo o devo tornare a iteratori per raggiungere questo obiettivo?

+3

perché non puoi usare remove_if/erase? –

+3

O semplicemente 'list :: remove_if', nessun iteratore necessario. –

+0

@KarthikT e @BenjaminLindley: Scusa, non ho menzionato nella mia domanda. Voglio fare qualcosa con gli elementi che soddisfano la condizione e anche con tutti gli altri. Probabilmente potrei inserire questo nella funzione di predicato usata da 'list :: remove_if', ma trovo che non sia molto bello. – Haatschii

risposta

6

Si dovrebbe essere in grado di fare solo questo

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

o semplicemente (per gentile concessione Benjamin Lindley)

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

gli elementi di spostamento sono piuttosto inefficienti per una lista –

+0

hm, bella modifica :) ma aspetta ... 'std :: erase'? hai provato a * compilare * questo? –

+2

@ Cheersandhth.-Alf Credo che tu stia sbagliando, la rimozione e l'inserimento sono O (1) per std :: list. Lo spostamento avverrà per contenitori sequenziali come std :: vector. –

0

No, io non la penso così. Vedi this SO answer:

No, non è possibile. L'intervallo basato su è per quando è necessario accedere a ciascun elemento di un contenitore una volta.

Si consiglia di utilizzare il normale ciclo for o di una delle sue cugine se è necessario modificare il contenitore come si va avanti, accedere a un elemento più di una volta, o in altro modo iterare in un modo non lineare attraverso il contenitore .

5

Non è possibile cancellare gli elementi di contenitori standard in un range-based per un ciclo su quel contenitore - il ciclo si ha un iteratore per l'elemento che si sta visitando, e la cancellazione si invaliderebbe che iteratore prima che il ciclo lo incrementi.

Range-based per è definito in 6.5.4 dello standard equivalente a (leggermente semplificata):

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

begin-expr e end-expr hanno la loro lunga definizione, ma nel tuo esempio essi sono myList.begin() e myList.end() rispettivamente.

Problemi correlati