lambda expression (tsz. lambda expressions)
Lambda kifejezések először C++11-ben jelentek meg, majd továbbfejlesztették őket C++14, C++17 és C++20 verziókban.
A lambda kifejezések általános formája:
(parameters) -> return_type { function_body };
Példa egy egyszerű lambda kifejezésre, amely két számot összead:
#include <iostream>
int main() {
auto add = (int a, int b) { return a + b; };
std::cout << "Összeg: " << add(5, 3) << std::endl; // Kimenet: Összeg: 8
return 0;
}
Itt: - Az add
változó egy lambda függvényt tartalmaz. - A jelzi, hogy a függvény nem kap semmilyen külső változót (capture list üres). -
(int a, int b)
paramétereket fogad. - { return a + b; }
a függvény törzse.
A capture list lehetővé teszi, hogy a lambda elérje a külső hatókörben lévő változókat.
→ Érték szerint (lemásolja az x
változót).
→ Referencia szerint (az x
változó eredeti példányát használja).
→ Minden külső változót érték szerint fogad el.
→ Minden külső változót referencia szerint fogad el.
→ Alapértelmezés szerint érték szerint, de y
-t referencia szerint.
→ Alapértelmezés szerint referencia szerint, de x
-et érték szerint.
#include <iostream>
int main() {
int a = 5;
auto lambda = () { std::cout << "a: " << a << std::endl; };
lambda();
a = 10; // Ez már nem változtatja meg a lambda belső a értékét
lambda(); // Az eredeti másolatot használja
return 0;
}
📌 Megjegyzés: A lambda az a
változót lemásolja, így ha a külső a
változik, az a lambda belsejére nincs hatással.
#include <iostream>
int main() {
int a = 5;
auto lambda = () { std::cout << "a: " << a << std::endl; };
lambda();
a = 10; // Most a lambda is ezt az új értéket látja
lambda();
return 0;
}
📌 Megjegyzés: A lambda referenciát használ, így ha az a
értéke megváltozik a külső hatókörben, az a lambda belsejére is hatással lesz.
A legtöbb esetben a C++ automatikusan kitalálja a visszatérési típust, de explicit módon is megadhatjuk.
auto multiply = (double a, double b) -> double {
return a * b;
};
📌 Mikor hasznos? Ha például különböző visszatérési típusok lehetnek:
auto example = (int x) -> std::string {
return (x > 0) ? "Pozitív" : "Negatív vagy nulla";
};
A lambda függvényeket gyakran használják az STL algoritmusokkal, például az std::sort
, std::for_each
, std::find_if
stb.
std::sort
lambda kifejezéssel#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {3, 1, 4, 1, 5, 9};
// Rendezzük a vektort csökkenő sorrendben lambda segítségével
std::sort(vec.begin(), vec.end(), (int a, int b) { return a > b; });
for (int n : vec) {
std::cout << n << " ";
}
return 0;
}
📌 Eredmény: 9 5 4 3 1 1
C++14-ben lehetővé vált, hogy automatikus típusokat (auto
) használjunk a lambda paramétereiben:
auto generic_lambda = (auto x, auto y) { return x + y; };
std::cout << generic_lambda(5, 3) << std::endl; // 8
std::cout << generic_lambda(2.5, 4.2) << std::endl; // 6.7
📌 Előny: A lambda különböző típusokkal is működik anélkül, hogy sablonokat kellene használni.
A mutable
kulcsszó lehetővé teszi, hogy a lambda módosítsa a lementett érték szerint átvett változókat:
#include <iostream>
int main() {
int x = 5;
auto lambda = () mutable { x++; std::cout << "x: " << x << std::endl; };
lambda();
lambda();
std::cout << "Eredeti x: " << x << std::endl; // x az eredeti marad!
return 0;
}
📌 Megjegyzés: Az x++
a lambda saját másolatán történik, az eredeti x
nem változik.
✅ Lambda kifejezések lehetővé teszik egyszerűbb, olvashatóbb és hatékonyabb kód írását.
✅ Hasznosak STL algoritmusokkal, párhuzamos programozásban, függvényparaméterként stb.
✅ Capture list lehetővé teszi külső változók elérését.
✅ C++14 óta generikus lambdák is elérhetők.
✅ mutable
segítségével érték szerint átvett változókat is módosíthatunk.