Ce face std::remove_if
std::remove_if funcționează ca std::remove, dar decide cu o funcție ce elemente dispar. Elementele păstrate sunt mutate la început, în ordinea inițială, iar funcția returnează noul sfârșit. Containerul nu se micșorează singur.
Ștergerea reală: v.erase(std::remove_if(v.begin(), v.end(), cond), v.end());. Din C++20 scrii simplu std::erase_if(v, cond), disponibil pentru vector, string, deque, list, dar și pentru map și set, unde remove_if nu se poate folosi.
Parametri
| Parametru | Descriere |
|---|---|
first, last |
Intervalul. |
conditie |
Funcție care returnează true pentru elementele de eliminat. |
Ce returnează
Iterator către noul sfârșit logic al intervalului.
Exemple
Exemplul 1: Eliminarea notelor sub 5 (erase-remove)
#include <algorithm>
#include <print>
#include <vector>
int main() {
std::vector<int> note{8, 4, 10, 3, 7, 4, 9};
note.erase(std::remove_if(note.begin(), note.end(), [](int n) { return n < 5; }), note.end());
std::println("{}", note);
}
Rezultat
[8, 10, 7, 9]
Exemplul 2: Același lucru cu std::erase_if (C++20)
#include <print>
#include <string>
#include <vector>
struct Produs {
std::string nume;
int stoc;
};
int main() {
std::vector<Produs> produse{{"Cafea", 12}, {"Ceai", 0}, {"Zahăr", 5}, {"Miere", 0}};
auto sterse = std::erase_if(produse, [](const Produs& p) { return p.stoc == 0; });
std::println("Am scos {} produse epuizate. Rămân:", sterse);
for (const Produs& p : produse) {
std::println(" {} ({})", p.nume, p.stoc);
}
}
Rezultat
Am scos 2 produse epuizate. Rămân:
Cafea (12)
Zahăr (5)
Exemplul 3: Varianta ranges
std::ranges::remove_if returnează subintervalul de „gunoi”, pe care îl dai direct lui erase.
#include <algorithm>
#include <cctype>
#include <print>
#include <string>
int main() {
std::string text = "Ana, are 3 mere!";
auto gunoi = std::ranges::remove_if(text, [](unsigned char c) { return std::ispunct(c); });
text.erase(gunoi.begin(), gunoi.end());
std::println("{}", text);
}
Rezultat
Ana are 3 mere
Greșeli frecvente
- Uiți
eraseși vectorul păstrează la final elemente vechi, cu valori nespecificate. - Încerci
std::remove_ifpe unstd::mapsaustd::set: nu compilează, pentru că cheile nu pot fi mutate. Foloseștestd::erase_if(m, ...). - Ștergi elemente din vector cu
eraseîntr-o buclăforcu index sau iterator, fără să ajustezi poziția. Sari peste elemente; erase-remove le tratează pe toate dintr-o trecere.
Comenzi înrudite
std::remove: Mută la final elementele egale cu o valoare și returnează noul sfârșit; ștergerea reală se face cu erase.std::copy_if: Copiază doar elementele care îndeplinesc o condiție, păstrând ordinea lor.std::partition: Împarte elementele în două grupuri: întâi cele care îndeplinesc condiția, apoi celelalte.std::erase_if: Șterge dintr-un container toate elementele egale cu o valoare (std::erase) sau care îndeplinesc o condiție (std::erase_if).