std::ranges::find în C++

Caută o valoare direct într-un container, opțional după un câmp al elementelor (proiecție).

Sintaxă
std::ranges::find(R&& r, const T& valoare, Proj proj = {});
std::ranges::find_if(R&& r, Pred conditie, Proj proj = {});

Ce face std::ranges::find

std::ranges::find(v, x) este varianta C++20 a lui std::find(v.begin(), v.end(), x). Returnează tot un iterator, care trebuie comparat cu v.end().

Cu proiecție poți căuta într-un vector de structuri după un câmp: std::ranges::find(clienti, "Ana", &Client::nume). Fără ranges ai fi avut nevoie de find_if și o lambda.

Dacă dai un container temporar (de exemplu rezultatul unei funcții), primești std::ranges::dangling în loc de iterator, ca să nu folosești un iterator către date distruse.

Parametri

Parametru Descriere
r Containerul sau range-ul.
valoare Valoarea căutată (comparată cu rezultatul proiecției).
proj Opțional. Câmpul sau funcția aplicată fiecărui element înainte de comparare.

Ce returnează

Iterator către primul element găsit, sau sfârșitul range-ului.

Exemple

Exemplul 1: Căutare simplă

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

int main() {
    std::vector<int> coduri{4021, 5530, 7712, 9001};

    auto it = std::ranges::find(coduri, 7712);
    if (it != coduri.end()) {
        std::println("Găsit pe poziția {}", std::distance(coduri.begin(), it));
    }
}

Rezultat

Găsit pe poziția 2

Exemplul 2: Căutare după câmp

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

struct Client {
    int id;
    std::string nume;
    std::string oras;
};

int main() {
    std::vector<Client> clienti{{1, "Ana", "Iași"}, {2, "Mihai", "Cluj"}, {3, "Elena", "Sibiu"}};

    auto it = std::ranges::find(clienti, "Mihai", &Client::nume);
    if (it != clienti.end()) {
        std::println("{} (id {}) din {}", it->nume, it->id, it->oras);
    }

    auto din_sibiu = std::ranges::find_if(clienti, [](const std::string& o) { return o == "Sibiu"; }, &Client::oras);
    std::println("Din Sibiu: {}", din_sibiu->nume);
}

Rezultat

Mihai (id 2) din Cluj
Din Sibiu: Elena

Greșeli frecvente

  • Folosești rezultatul fără să verifici it != v.end().
  • Cauți într-un vector returnat de o funcție (std::ranges::find(citeste(), x)) și încerci să dereferențiezi rezultatul: este dangling și nu compilează. Salvează mai întâi vectorul într-o variabilă.

Comenzi înrudite

  • std::find: Caută prima apariție a unei valori într-un interval și returnează un iterator către ea.
  • std::find_if: Găsește primul element care îndeplinește o condiție (find_if) sau primul care nu o îndeplinește (find_if_not).
  • std::ranges::sort: Sortează un container întreg dintr-un apel, cu opțiunea de a sorta după un câmp (proiecție).
  • std::views::filter: Creează o vedere asupra unui container care conține doar elementele ce îndeplinesc o condiție, fără copiere.