2014-10-23 16 views
5

Czy istnieje sposób na usunięcie określonych elementów podczas używania zmiennej automatycznej w pętli for?Wymazywanie elementu w pętli automatycznej dla (-ej)

for(auto a: m_Connections) 
{ 
    if(something) 
    { 
     //Erase this element 

    } 
} 

wiem, że mogę albo mów

for(auto it=m_map.begin() ... 

lub

for(map<int,int>::iterator it=m_map.begin() ... 

i ręcznie zwiększać iterator (i usuwać), ale jeśli mogę to zrobić z mniej linii kodu I byłby szczęśliwszy.

Dzięki!

+0

Co masz na myśli podczas wymazywania? – Etixpp

+0

m_Connections.erase (it); w "innych przykładach". – Valmond

Odpowiedz

5

Nie, nie ma. Pętla oparta na zasięgach służy do jednorazowego dostępu do każdego elementu kontenera.

Za każdym razem, gdy element jest usuwany z kontenera, iteratory po usuniętym elemencie lub po nim nie są już ważne (i podany the implementation of the range-based-for jest to problem).

Powinieneś użyć normalnej pętli for (lub while), jeśli musisz zmodyfikować kontener w trakcie jazdy.

Jeśli chcesz usunąć elementy, dla którego predykat zwraca true, dobrym sposobem jest:

m_Connections.erase(
    std::remove_if(m_Connections.begin(), 
       m_Connections.end(), 
       [](Type elem) { return predicate(elem); }), 
    m_Connections.end()); 

std::remove_if nie mieszać iteracji logiki orzecznika.

1

Push wszystkich elementów w tablicy, a następnie wykonaj operację pop usunąć element

+0

Nie przyniosłoby to dokładniejszego kodu, który był celem OP. – joaerl

3

Musisz iteracyjnej, jeśli chcesz, aby usunąć element z pojemnika.
I nie można pobrać iteratora z samego elementu - i nawet gdybyś mógł, na przykład z vector, iterator, który byłby oparty na zakresie dla wewnętrznych zastosowań, zostałby unieważniony w następnym kroku powodując niezdefiniowane zachowanie.

Odpowiedź brzmi: Nie, w klasycznym użyciu nie można. oparty na zakresie został zaprojektowany wyłącznie do wygodnej iteracji wszystkich elementów w zakresie.

5

Nie możesz. Pętla bazująca na odległościach sprawia, że ​​prosta iteracja w pewnym zakresie jest łatwiejsza, ale nie obsługuje niczego, co unieważnia zakres lub iterator, którego używa. Oczywiście, nawet jeśli byłyby one obsługiwane, nie można skutecznie usunąć elementu bez dostępu do iteratora.

Musisz pętli starej szkoły, wzdłuż linii

for (auto it = container.begin(); it != container.end();) { 
    if (something) { 
     it = container.erase(it); 
    } else { 
     ++it; 
    } 
} 

lub kombinacji container.erase() i std::remove_if, jeśli lubisz tego rodzaju rzeczy.

+0

Osobisty smak: użyj 'while (it! = End (container)) {}' – Alex