std::views::filter în C++

Creează o vedere asupra unui container care conține doar elementele ce îndeplinesc o condiție, fără copiere.

Sintaxă
auto v = range | std::views::filter(conditie);

Ce face std::views::filter

std::views::filter nu copiază și nu modifică nimic: întoarce o „vedere” (view) care, când o parcurgi, sare peste elementele pentru care condiția este false. Calculul se face leneș, în timpul parcurgerii.

View-urile se combină cu operatorul |, ca într-o conductă: v | filter(...) | transform(...) | take(3). Dacă modifici containerul original, vederea vede datele noi.

Echivalentul clasic, care copiază, este std::copy_if.

Parametri

Parametru Descriere
range Containerul sau alt view.
conditie Funcție care primește un element și returnează bool.

Ce returnează

Un view cu elementele care trec de filtru.

Exemple

Exemplul 1: Numerele pare

#include <print>
#include <ranges>
#include <vector>

int main() {
    std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8};

    for (int x : v | std::views::filter([](int n) { return n % 2 == 0; })) {
        std::print("{} ", x);
    }
    std::println("");
}

Rezultat

2 4 6 8

Exemplul 2: Conductă de view-uri

Primele două produse din Iași, cu numele cu majuscule. Nimic nu se copiază până la afișare.

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

struct Comanda {
    std::string client;
    std::string oras;
    double total;
};

int main() {
    std::vector<Comanda> comenzi{
        {"Ana", "Iași", 120.5}, {"Dan", "Cluj", 89.0}, {"Ioana", "Iași", 310.0}, {"Radu", "Iași", 45.0}};

    auto din_iasi = comenzi
                  | std::views::filter([](const Comanda& c) { return c.oras == "Iași"; })
                  | std::views::take(2);

    for (const Comanda& c : din_iasi) {
        std::println("{}: {:.2f} lei", c.client, c.total);
    }
}

Rezultat

Ana: 120.50 lei
Ioana: 310.00 lei

Greșeli frecvente

  • Modifici elementele printr-un filter astfel încât nu mai îndeplinesc condiția, apoi parcurgi vederea din nou: comportament nedefinit. Filtrul își amintește poziții deja găsite.
  • Declari parametrul unei funcții ca const auto& pentru un view filtrat și încerci să-l parcurgi: filter_view nu se poate parcurge prin const. Primește-l prin valoare sau prin referință simplă.

Comenzi înrudite

  • std::views::transform: Creează o vedere în care fiecare element este rezultatul unei funcții aplicate elementului original.
  • std::copy_if: Copiază doar elementele care îndeplinesc o condiție, păstrând ordinea lor.
  • std::ranges::to: Transformă un range sau un view (filtrat, transformat) într-un container nou: vector, set, string, map.
  • std::views::take_while: Creează o vedere cu elementele de la început, cât timp îndeplinesc o condiție; se oprește la primul care nu o îndeplinește.