Beruflich Dokumente
Kultur Dokumente
a presupunem ca vrem sa scriem un program care sa genereze o secventa de numere aleatoare pe care sa le afiseze in consola, apoi dintre acestea sa selecteze acele
numere care sunt pare si sa afiseze aceasta secventa in consola. Un astfel de program ar putea arata asa:
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <iterator>
#include <ctime>
int main()
{
srand((unsigned long)time(NULL));
return 0;
}
41 67 34 0 69 24 78 58 62 64
34 0 24 78 58 62 64
int main()
{
srand((unsigned long)time(NULL));
return 0;
}
Dupa cum se vede, codul e mai scurt, nu mai avem nevoie de functia randomizer() si nici de functorul isodd, in schimb am introdus cateva constructii noi:
[] {return rand()%100;}
Acestea se numesc lambda si sunt constructii similare celor introduse cu cativa ani in urma in .NET. In C++ o expresie lambda are cateva componente. Sa luam spre
exemplu ultima dintre acestea.
lambda-introducer: aceasta este partea introductiva, care spune compilatorului ca urmeaza o expresie lambda; aici se specifica si ce variabile si in ce mod
(valoare sau referinta) se copiaza din blocul in care expresia lambda este definita (vom vedea acest lucru mai jos).
lambda-parameter-declaration: specifica parametrii expresiei lambda.
lambda-return-type-clause: specifica tipul la care se evalueaza expresia lambda; aceasta parte este optionala, cel mai adesea compilatorul putand deduce
implicit care este tipul expresiei. Este necesara specificare explicita a tipului doar atunci cand tipul valorii returnate este ambiguu. Pentru exemplul anterior
specificarea tipului valori returnate (> bool) nu este necesara.
compound-statement: reprezinta corpul expresiei lambda.
Iata un exemplu in care compilatorul nu poate deduce tipul returnat, si acesta trebuie specificat explicit:
vector<int> v1;
transform(v1.begin(), v1.end(), v1.begin(), [](int n) {
if(n > 0)
return n * 2;
else
return 0;
});
1>lambdas.cpp(68): error C3499: a lambda that has been specified to have a void return type cannot return a value
1>lambdas.cpp(70): error C3499: a lambda that has been specified to have a void return type cannot return a value
http://www.codexpert.ro/articole.php?id=30 3/8
1/27/2019 CODEXPERT: Expresii lambda in C++
Exista doua tipuri de expresii lambda: cu si fara stare. Cele pe care le-am vazut in exemplele de mai sus sunt fara stare. Ele nu contin variabile membru. Astfel de
lambda sunt introduse cu []. Se pot insa captura variabile din scopul in care este declarata expresia lambda, atat prin valoare cat si prin referinta. In acest caz vorbim de
lambda cu stare. Pentru a vedea modurile in care se pot capta variabile sa plecam de la exemplul urmator.
void function()
{
int a;
int b;
int c;
Dupa cum se observa se pot captura variabile prin copiere si valoare in orice combinatie posibila. Un caz special il reprezinta captarea pointerului this, care se face
intotdeauza prin valoare. Nu se poate specifica &this.
In exemplul de mai jos avem definita o clasa Range (cu un minim si maxim) care contine o functie ce filtreaza acele elemente ale unui vector care nu sunt intre limite,
returnand un vector nou doar cu elementele din raza de valori.
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <iterator>
#include <ctime>
return output;
}
};
int main()
{
srand((unsigned long)time(NULL));
http://www.codexpert.ro/articole.php?id=30 5/8
1/27/2019 CODEXPERT: Expresii lambda in C++
return 0;
}
45 41 24 7 10 12 98 33 7 14
24 7 10 12 7 14
Urmatorul exemplu arata o functie lambda folosita pentru a calcula suma numerelor dintr-o secventa.
int main()
{
srand((unsigned long)time(NULL));
// calculeaza suma
int sum = 0;
for_each(v1.begin(), v1.end(), [&sum] (int n) {sum += n;});
// afiseaza suma
cout << "sum = " << sum << endl;
http://www.codexpert.ro/articole.php?id=30 6/8
1/27/2019 CODEXPERT: Expresii lambda in C++
return 0;
}
57 96 17 43 2 79 24 44 14 93
sum = 469
Variabila sum este capturata prin referinta, astfel incat valoare ei poate fi modificata. Expresia lambda din acest exemplu este transformata de compilator intr-un
functor.
class lambda_functor
{
int& m_sum;
public:
lambda_functor(int& sum) : m_sum(sum) {}
int sum = 0;
for_each(v1.begin(), v1.end(), [&sum] (int n) {sum += n;});
devine
int sum = 0;
for_each(v1.begin(), v1.end(), lambda_functor(sum));
Datorita faptului ca functiile lambda sunt transformate de compilator in functori (function objects) acestea pot fi stocate in std::tr1::function. Iata un exemplu:
#include <iostream>
#include <vector>
#include <functional>
http://www.codexpert.ro/articole.php?id=30 7/8
1/27/2019 CODEXPERT: Expresii lambda in C++
#include <algorithm>
#include <iterator>
#include <string>
int main()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
vector<string> v2;
v2.push_back("marius");
v2.push_back("bancila");
v2.push_back("codexpert");
return 0;
}
Pentru alte informatii despre functiile lambda vedeti blogul echipei VC++. Informatii despre calculul lambda in matematica si programare se pot gasi
pe wikipedia. [phpBB Debug] PHP Warning: in file [ROOT]/phpbb/db/driver/mysqli.php on line 317: mysqli_free_result(): Couldn't fetch mysqli_result
http://www.codexpert.ro/articole.php?id=30 8/8