Sostieni AppuntiFacili con una piccola donazione su PayPal
Dona con PayPalLe lambda in C++ sono funzioni anonime che possono essere definite direttamente all’interno del codice, senza dover dichiarare un nome. Sono particolarmente utili per:
Passare funzioni come argomenti a funzioni standard (std::sort, std::for_each, ecc.);
Definire piccoli comportamenti inline senza creare funzioni separate;
Catturare variabili locali in modo flessibile.
Le lambda sono state introdotte in C++11 e sono diventate uno strumento fondamentale per scrivere codice moderno e conciso.
INFO
Esempio pratico: se vuoi ordinare un vettore di numeri in ordine decrescente senza scrivere una funzione separata, puoi usare una lambda direttamente dentro std::sort.
La sintassi di una lambda è:
[capture](parameters) -> return_type { body }
Dove:
Esempio semplice:
#include <iostream>
int main() {
auto somma = [](int a, int b) { return a + b; };
std::cout << somma(3, 5) << std::endl; // Output: 8
}
Le lambda possono catturare variabili locali per poterle usare all’interno del loro corpo.
| Modalità | Descrizione | Esempio |
|---|---|---|
[=] | Cattura tutte le variabili esterne per valore | [=](int x){ return x + a; } |
[&] | Cattura tutte le variabili esterne per riferimento | [&](int x){ a++; return x + a; } |
[a] | Cattura solo la variabile a per valore | [a](int x){ return x + a; } |
[&a] | Cattura solo la variabile a per riferimento | [&a](int x){ a++; return x; } |
Esempio pratico:
#include <iostream>
int main() {
int a = 10;
int b = 5;
auto lambda1 = [=]() { return a + b; }; // cattura per valore
auto lambda2 = [&]() { a += b; return a; }; // cattura per riferimento
std::cout << lambda1() << std::endl; // 15
std::cout << lambda2() << std::endl; // 15, a diventa 15
}
INFO
La differenza tra cattura per valore e riferimento è importante: per valore copia le variabili, per riferimento le modifica direttamente.
Se la lambda è complessa, possiamo specificare il tipo di ritorno usando -> type:
#include <iostream>
int main() {
auto max = [](int a, int b) -> int {
return (a > b) ? a : b;
};
std::cout << max(10, 20) << std::endl; // 20
}
Se il tipo di ritorno è deducibile, possiamo omettere -> type.
Le lambda sono molto utili con le funzioni della Standard Template Library (STL), come std::for_each, std::sort e std::find_if.
Esempio con std::for_each:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numeri = {1, 2, 3, 4, 5};
std::for_each(numeri.begin(), numeri.end(), [](int n){
std::cout << n * 2 << " ";
});
// Output: 2 4 6 8 10
}
Esempio con std::sort:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numeri = {5, 2, 8, 1};
std::sort(numeri.begin(), numeri.end(), [](int a, int b) {
return a > b; // ordine decrescente
});
for (auto n : numeri) std::cout << n << " "; // 8 5 2 1
}
Per default, le lambda che catturano per valore non possono modificare le variabili catturate.
Usando mutable, possiamo modificarle internamente:
#include <iostream>
int main() {
int a = 5;
auto lambda = [a]() mutable {
a += 10;
return a;
};
std::cout << lambda() << std::endl; // 15
std::cout << a << std::endl; // 5, fuori non cambia
}
Scrivi un programma che:
Crea un programma che:
x e y;x e y usando la cattura per valore;x di y usando la cattura per riferimento;std::vector<int> con valori casuali;std::for_each con una lambda per stampare ogni valore moltiplicato per 3;std::sort con una lambda per ordinare il vettore in ordine decrescente.INFO
Questo esercizio aiuta a capire come le lambda possono mantenere uno stato interno senza modificare le variabili esterne.
1) Cosa è una lambda in C++?
2) Quale sintassi indica la cattura per riferimento?
3) Come si specifica il tipo di ritorno di una lambda?
4) Qual è il comportamento di una lambda con cattura per valore?
5) Come si usa una lambda con std::sort per ordinare un vettore in ordine decrescente?
6) Cosa fa l'opzione mutable in una lambda?