std::remove în C++

Mută la final elementele egale cu o valoare și returnează noul sfârșit; ștergerea reală se face cu erase.

Sintaxă
ForwardIt remove(ForwardIt first, ForwardIt last, const T& valoare);

Ce face std::remove

Numele înșală: std::remove nu micșorează containerul. Algoritmul nu are acces la vector, doar la iteratori, așa că mută elementele care rămân spre început și returnează un iterator către noul sfârșit logic. Ce se află după el este „gunoi” cu valori nespecificate.

De aceea se folosește împreună cu metoda erase a containerului, într-un tipar numit erase-remove: v.erase(std::remove(v.begin(), v.end(), x), v.end());.

Din C++20 există varianta mai simplă std::erase(v, x), care face ambii pași și returnează câte elemente au fost șterse.

Parametri

Parametru Descriere
first, last Intervalul.
valoare Valoarea eliminată.

Ce returnează

Iterator către noul sfârșit al intervalului (primul element „gunoi”).

Exemple

Exemplul 1: Ce face remove fără erase

Dimensiunea rămâne 7. Primele 4 poziții conțin elementele păstrate; ultimele 3 sunt resturi.

#include <algorithm>
#include <print>
#include <vector>

int main() {
    std::vector<int> v{1, 0, 2, 0, 3, 0, 4};

    auto nou_sfarsit = std::remove(v.begin(), v.end(), 0);

    std::println("Dimensiune: {}", v.size());
    std::println("Păstrate: {}", std::vector<int>(v.begin(), nou_sfarsit));
}

Rezultat

Dimensiune: 7
Păstrate: [1, 2, 3, 4]

Exemplul 2: Tiparul erase-remove

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

int main() {
    std::vector<std::string> lista{"lapte", "pâine", "ouă", "pâine", "unt"};

    lista.erase(std::remove(lista.begin(), lista.end(), "pâine"), lista.end());

    std::println("{} elemente: {}", lista.size(), lista);
}

Rezultat

3 elemente: ["lapte", "ouă", "unt"]

Exemplul 3: Varianta C++20: std::erase

Pe std::string funcționează la fel: aici eliminăm toate spațiile.

#include <print>
#include <string>

int main() {
    std::string telefon = "0722 123 456";

    auto sterse = std::erase(telefon, ' ');
    std::println("{} (au fost eliminate {} spații)", telefon, sterse);
}

Rezultat

0722123456 (au fost eliminate 2 spații)

Greșeli frecvente

  • Apelezi doar std::remove(v.begin(), v.end(), x) și te aștepți ca v.size() să scadă. Fără erase, vectorul păstrează aceeași dimensiune.
  • Scrii v.erase(std::remove(...)) fără al doilea argument v.end(). Se șterge un singur element, nu tot restul.

Comenzi înrudite

  • std::remove_if: Elimină logic elementele care îndeplinesc o condiție; folosit cu erase sau înlocuit de std::erase_if (C++20).
  • std::unique: Elimină duplicatele aflate unul lângă altul; după sortare, elimină toate duplicatele.
  • std::replace: Înlocuiește pe loc toate elementele egale cu o valoare (replace) sau care îndeplinesc o condiție (replace_if).