std::vector::erase în C++

std::vector C++98

Șterge un element sau un interval de elemente din vector și returnează iteratorul elementului de după.

Sintaxă
iterator erase(const_iterator poz);
iterator erase(const_iterator prim, const_iterator ultim);

Ce face std::vector::erase

erase(poz) șterge elementul indicat de iterator, iar erase(prim, ultim) șterge intervalul [prim, ultim) (fără ultim). Elementele de după se mută spre stânga ca să umple golul, deci vectorul rămâne compact.

Invalidare: iteratorii și referințele de la poziția ștearsă până la final (inclusiv end()) devin invalide. Cele dinainte rămân valide. Valoarea returnată este un iterator valid la elementul care a urmat după cele șterse; folosește-o când ștergi într-o buclă.

Ca să ștergi toate elementele egale cu o valoare sau care îndeplinesc o condiție, în C++20 cel mai simplu este std::erase(v, valoare) sau std::erase_if(v, conditie).

Parametri

Parametru Descriere
poz Iterator la elementul de șters (nu end()).
prim, ultim Intervalul de șters: de la prim inclusiv până la ultim exclusiv.

Ce returnează

Un iterator la elementul de după ultimul element șters (poate fi end()).

Exemple

Exemplul 1: Ștergerea unui element și a unui interval

#include <print>
#include <vector>

int main() {
    std::vector<int> v{10, 20, 30, 40, 50, 60};
    v.erase(v.begin());                    // șterge 10
    std::println("{}", v);
    v.erase(v.begin() + 1, v.begin() + 3); // șterge 30 și 40
    std::println("{}", v);
    v.erase(v.end() - 1);                  // șterge ultimul
    std::println("{}", v);
}

Rezultat

[20, 30, 40, 50, 60]
[20, 50, 60]
[20, 50]

Exemplul 2: Ștergere corectă într-o buclă

Când ștergem, nu facem ++it: erase ne-a dat deja iteratorul următorului element.

#include <print>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> comenzi{"anulată", "livrată", "anulată", "în curs", "livrată"};
    for (auto it = comenzi.begin(); it != comenzi.end(); ) {
        if (*it == "anulată") {
            it = comenzi.erase(it);     // it indică elementul de după cel șters
        } else {
            ++it;
        }
    }
    std::println("{}", comenzi);
}

Rezultat

["livrată", "în curs", "livrată"]

Exemplul 3: Ștergerea după poziție (indice)

#include <print>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> elevi{"Ana", "Bogdan", "Carmen", "Dan"};
    std::size_t poz = 2;
    elevi.erase(elevi.begin() + static_cast<std::ptrdiff_t>(poz));
    std::println("{}", elevi);
}

Rezultat

["Ana", "Bogdan", "Dan"]

Greșeli frecvente

  • Scrii v.erase(it); ++it; în buclă. După erase, it este invalid (comportament nedefinit). Folosește it = v.erase(it); și nu mai incrementa în acel pas.
  • Ștergi elemente într-o buclă for (auto x : v). Iteratorii folosiți de buclă sunt invalidați; folosește std::erase_if.
  • Apelezi v.erase(v.end()). end() nu este un element, deci nu poate fi șters (comportament nedefinit).

Comenzi înrudite

  • std::erase_if: Șterge dintr-un container toate elementele egale cu o valoare (std::erase) sau care îndeplinesc o condiție (std::erase_if).
  • std::vector::insert: Inserează unul sau mai multe elemente înaintea unei poziții din vector; emplace construiește elementul pe loc.
  • std::vector::clear: Șterge toate elementele vectorului; dimensiunea devine 0, dar memoria rezervată rămâne.
  • std::vector::pop_back: Șterge ultimul element al vectorului; dimensiunea scade cu 1.
  • std::remove_if: Elimină logic elementele care îndeplinesc o condiție; folosit cu erase sau înlocuit de std::erase_if (C++20).