Espressione Lambda in C++
C++ 11 ha introdotto le espressioni lambda per consentire funzioni inline che possono essere utilizzate per brevi frammenti di codice che non verranno riutilizzati e quindi non richiedono un nome. Nella loro forma più semplice un'espressione lambda può essere definita come segue:
[ capture clause ] (parameters) ->return-type { definizione del metodo } Generalmente, il tipo restituito nelle espressioni lambda viene valutato dal compilatore stesso e non è necessario specificarlo esplicitamente. Anche la parte -> return-type può essere ignorata. Tuttavia, in alcuni casi complessi, ad es. istruzioni condizionali, il compilatore non può determinare il tipo restituito ed è richiesta una specifica esplicita.
Di seguito sono riportati vari usi dell'espressione lambda con funzioni standard:
CPP
// C++ program to demonstrate lambda expression in C++> #include> using> namespace> std;> // Function to print vector> void> printVector(vector <> int> >v)> {> > // lambda expression to print vector> > for_each(v.begin(), v.end(), [](> int> i)> > {> > std::cout < < i < <> ' '> ;> > });> > cout < < endl;> }> int> main()> {> > vector <> int> >in {4, 1, 3, 5, 2, 3, 1, 7};> > printVector(v);> > // below snippet find first number greater than 4> > // find_if searches for an element for which> > // function(third argument) returns true> > vector <> int> >:: iteratore p = find_if(v.begin(), v.end(), [](> int> i)> > {> > return> i>4;> > });> > cout < <> 'First number greater than 4 is : '> < < *p < < endl;> > // function to sort vector, lambda expression is for sorting in> > // non-increasing order Compiler can make out return type as> > // bool, but shown here just for explanation> > sort(v.begin(), v.end(), [](> const> int> & a,> const> int> & b) ->> bool> > {> > return> a>b;> > });> > printVector(v);> > // function to count numbers greater than or equal to 5> > int> count_5 = count_if(v.begin(), v.end(), [](> int> a)> > {> > return> (a>= 5);> > });> > cout < <> 'The number of elements greater than or equal to 5 is : '> > < < count_5 < < endl;> > // function for removing duplicate element (after sorting all> > // duplicate comes together)> > p = unique(v.begin(), v.end(), [](> int> a,> int> b)> > {> > return> a == b;> > });> > // resizing vector to make size equal to total different number> > v.resize(distance(v.begin(), p));> > printVector(v);> > // accumulate function accumulate the container on the basis of> > // function provided as third argument> > int> arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};> > int> f = accumulate(arr, arr + 10, 1, [](> int> i,> int> j)> > {> > return> i * j;> > });> > cout < <> 'Factorial of 10 is : '> < < f < < endl;> > // We can also access function by storing this into variable> > auto> square = [](> int> i)> > {> > return> i * i;> > };> > cout < <> 'Square of 5 is : '> < < square(5) < < endl;> }> |
Produzione:
4 1 3 5 2 3 1 7 First number greater than 4 is : 5 7 5 4 3 3 2 1 1 The number of elements greater than or equal to 5 is : 2 7 5 4 3 2 1 Factorial of 10 is : 3628800 Square of 5 is : 25
Un'espressione lambda può avere più potere di una funzione ordinaria avendo accesso alle variabili dall'ambito che la racchiude. Possiamo catturare variabili esterne dall'ambito di inclusione in tre modi:
Cattura per riferimento
Cattura in base al valore
Cattura da entrambi (cattura mista)
Sintassi utilizzata per acquisire le variabili:
[&]: cattura tutte le variabili esterne per riferimento
[=]: cattura tutte le variabili esterne in base al valore
[a, &b]: cattura a per valore e b per riferimento
Una lambda con una clausola di cattura vuota [ ] può accedere solo alle variabili ad essa locali.
Di seguito sono illustrati diversi metodi di acquisizione:
CPP
// C++ program to demonstrate lambda expression in C++> #include> using> namespace> std;> int> main()> {> > vector <> int> >v1 = {3, 1, 7, 9};> > vector <> int> >v2 = {10, 2, 7, 16, 9};> > // access v1 and v2 by reference> > auto> pushinto = [&] (> int> m)> > {> > v1.push_back(m);> > v2.push_back(m);> > };> > // it pushes 20 in both v1 and v2> > pushinto(20);> > // access v1 by copy> > [v1]()> > {> > for> (> auto> p = v1.begin(); p != v1.end(); p++)> > {> > cout < < *p < <> ' '> ;> > }> > };> > int> N = 5;> > // below snippet find first number greater than N> > // [N] denotes, can access only N by value> > vector <> int> >:: iteratore p = find_if(v1.begin(), v1.end(), [N](> int> i)> > {> > return> i>N;> > });> > cout < <> 'First number greater than 5 is : '> < < *p < < endl;> > // function to count numbers greater than or equal to N> > // [=] denotes, can access all variable> > int> count_N = count_if(v1.begin(), v1.end(), [=](> int> a)> > {> > return> (a>=N);> > });> > cout < <> 'The number of elements greater than or equal to 5 is : '> > < < count_N < < endl;> }> |
Produzione:
First number greater than 5 is : 7 The number of elements greater than or equal to 5 is : 3
Nota: le espressioni Lambda sono disponibili dopo C++ 11.