2014-10-23 6 views
5

Gibt es eine Möglichkeit, bestimmte Elemente zu löschen, wenn eine Auto-Variable in einer for-Schleife wie dieser verwendet wird?Element in einer for (-each) Auto-Schleife löschen

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

    } 
} 

Ich weiß, ich kann entweder sagen

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

oder

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

und manuell den Iterator erhöhen (und löschen), aber wenn ich es mit weniger Code-Zeilen ich tun konnte, wäre glücklicher.

Danke!

+0

Was meinst du mit löschen? – Etixpp

+0

m_Connections.erase (it); in den "anderen Beispielen". – Valmond

Antwort

5

Nein, gibt es nicht. Bereichsbasiert für eine Schleife wird verwendet, um einmal auf jedes Element eines Containers zuzugreifen.

Jedes Mal, wenn ein Element aus dem Container entfernt wird, sind Iteratoren bei oder nach dem gelöschten Element nicht mehr gültig (und the implementation of the range-based-for ist dies ein Problem).

Sie sollten die normale for-Schleife (oder eine while) verwenden, wenn Sie den Container ändern müssen, während Sie fortfahren.

Wenn Sie Elemente löschen, für die ein Prädikat true zurückgibt, ist ein guter Weg:

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

std::remove_if nicht Iterationslogik mit dem Prädikat mischt.

1

Push alle Elemente in ein Array und tun dann Pop-Operation das Element

+0

Würde nicht genau in weniger Code resultieren, was das Ziel für OP war. – joaerl

3

Sie müssen den Iterator zu entfernen, wenn Sie ein Element aus einem Container löschen möchten.
Und Sie können nicht den Iterator aus dem Element selbst erhalten - und auch wenn Sie könnten, zum Beispiel mit vector, würde der Iterator, der für interne Verwendungen range-based verwendet im nächsten Schritt ungültig und verursacht undefiniertes Verhalten.

Also die Antwort ist: Nein, in seiner klassischen Verwendung können Sie nicht. range-based for wurde ausschließlich für die bequeme Iteration aller Elemente in einem Bereich entwickelt.

5

Sie können nicht. Eine bereichsbasierte Schleife macht eine einfache Iteration über einen Bereich einfacher, unterstützt jedoch nichts, was den Bereich oder den verwendeten Iterator ungültig macht. Selbst wenn dies unterstützt würde, könnten Sie natürlich ein Element ohne Zugriff auf den Iterator nicht effizient löschen. wenn Sie

Sie erhalten eine Old-School-Schleife benötigen, entlang der Linien von

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

oder eine Kombination aus container.erase() und std::remove_if, wie diese Art der Sache.

+0

persönliche Geschmack: Verwenden Sie 'while (it! = Ende (Container)) {}' – Alex