Ce face lambda ([](){})
O expresie lambda creează o funcție pe loc. Forma de bază: [](int x) { return x * 2; }. O poți salva într-o variabilă (auto dublu = ...;) și apela ca pe orice funcție, sau o poți da direct unui algoritm, ca std::sort sau std::count_if.
Parantezele drepte sunt lista de captură: ce variabile din jur vede lambda. [x] copiază x, [&x] îl folosește prin referință (și îl poate modifica), [=] copiază tot ce folosește, [&] folosește totul prin referință, [this] captează obiectul curent.
Tipul returnat este dedus din return; îl poți scrie explicit cu -> tip. Din C++14, parametrii pot fi auto (lambda generică), iar din C++20 lambda poate avea și listă de șablon: []<typename T>(T x) { ... }.
Exemple
Exemplul 1: Lambda ca funcție obișnuită
#include <print>
int main() {
auto cu_tva = [](double pret) { return pret * 1.21; };
auto saluta = [](const char* nume) { std::println("Bună, {}!", nume); };
std::println("100 lei cu TVA: {:.2f}", cu_tva(100));
saluta("Ioana");
}
Rezultat
100 lei cu TVA: 121.00
Bună, Ioana!
Exemplul 2: Lambda cu algoritmi
Lambda dată lui std::sort spune cum se compară două elemente; cea dată lui std::count_if spune ce elemente se numără. prag este capturat prin copie.
#include <algorithm>
#include <print>
#include <string>
#include <vector>
struct Produs {
std::string nume;
double pret;
};
int main() {
std::vector<Produs> produse = {{"Telefon", 1999}, {"Husă", 49}, {"Căști", 299}};
std::sort(produse.begin(), produse.end(),
[](const Produs& a, const Produs& b) { return a.pret < b.pret; });
for (const auto& p : produse) {
std::println("{}: {} lei", p.nume, p.pret);
}
double prag = 100;
auto scumpe = std::count_if(produse.begin(), produse.end(),
[prag](const Produs& p) { return p.pret > prag; });
std::println("Produse peste {} lei: {}", prag, scumpe);
}
Rezultat
Husă: 49 lei
Căști: 299 lei
Telefon: 1999 lei
Produse peste 100 lei: 2
Exemplul 3: Captură prin referință și lambda generică
[&total] modifică variabila din main. Lambda maxim are parametri auto, deci merge cu orice tip comparabil.
#include <print>
#include <string>
#include <vector>
int main() {
double total = 0;
auto adauga = [&total](double suma) { total += suma; };
adauga(150);
adauga(49.5);
std::println("Total coș: {} lei", total);
auto maxim = [](auto a, auto b) { return a > b ? a : b; };
std::println("{} {} {}", maxim(3, 8), maxim(2.5, 1.5), maxim(std::string("Ana"), std::string("Dan")));
}
Rezultat
Total coș: 199.5 lei
8 2.5 Dan
Greșeli frecvente
- Capturezi prin referință (
[&]) o variabilă locală și păstrezi lambda după ce funcția s-a terminat (o returnezi sau o salvezi într-unstd::function). Referința rămâne „atârnată”: comportament nedefinit. Capturează prin copie în acest caz. - Încerci să modifici o variabilă capturată prin copie:
[x]() { ++x; }. Nu se compilează; folosește[&x]sau marchează lambdamutable. - Folosești
[=]într-o metodă și crezi că membrii clasei sunt copiați. Este capturat doar pointerulthis; dacă obiectul dispare, lambda accesează memorie invalidă.
Comenzi înrudite
mutable: Permite modificarea unui membru chiar și în metode const sau modificarea variabilelor capturate prin copie într-o lambda.auto: Lasă compilatorul să deducă tipul variabilei din valoarea cu care este inițializată.operator: Definește ce face un operator (+, ==, <<, [], () etc.) pentru tipurile tale, ca obiectele să se folosească la fel de natural ca numerele.template: Scrie o funcție sau o clasă o singură dată, pentru orice tip; compilatorul generează varianta potrivită pentru fiecare tip folosit.std::function: Variabilă care poate ține orice funcție, lambda sau obiect apelabil cu o anumită semnătură.std::sort: Sortează elementele dintr-un interval, crescător sau după o regulă dată de tine.