lambda capture by reference
Főnév
lambda capture by reference (tsz. lambda capture by references)
- (informatika) A C++-ban a lambda függvények lehetővé teszik, hogy névtelen függvényeket definiáljunk és inline módon használjunk.
A lambda szintaxisa:
[capture](parameter_list) -> return_type { body }
A capture listában megmondhatjuk, hogy a lambda milyen külső változókat “vigyen magával”, és hogyan:
- érték szerint (
by value) → másolat - referencia szerint (
by reference) → hivatkozás
Most a referencia szerinti befogást vizsgáljuk.
1️⃣ Mi az a capture by reference?
Capture by reference azt jelenti, hogy a lambda nem másolatot készít a változóról, hanem hivatkozást visz magával:
- a lambda a változó eredeti példányára fog hivatkozni
- ha a külső változó megváltozik, a lambda látni fogja a változást
- a lambda belsejéből a változó módosítható is
Szintaxis:
[&x] // csak az 'x' változót fogjuk be referenciaként
[&] // minden használt külső változót referenciaként fogunk be
2️⃣ Példa: egyszerű capture by reference
#include <iostream>
int main() {
int x = 10;
auto lambda = [&x]() {
std::cout << "x inside lambda: " << x << std::endl;
};
x = 20;
lambda();
}
Kimenet:
x inside lambda: 20
Miért?
- A
[&x]miatt a lambda referenciaként viszi magával azx-et. - Ezért amikor
x = 20;megtörténik, a lambda is látja az új értéket.
3️⃣ Globális capture by reference
Ha az összes használt külső változót referenciaként akarod befogni, használhatod a [&] szintaxist:
#include <iostream>
int main() {
int x = 5;
int y = 8;
auto lambda = [&]() {
std::cout << "x: " << x << ", y: " << y << std::endl;
};
x = 100;
y = 200;
lambda();
}
Kimenet:
x: 100, y: 200
4️⃣ Mikor érdemes capture by reference-t használni?
Capture by reference akkor hasznos, ha:
✅ A lambda futásakor mindig az aktuális értéket akarod látni ✅ A lambdán belül módosítani akarod a külső változót ✅ Nagy méretű objektumokat használsz, amiket nem akarsz másolni
5️⃣ Capture by reference → módosítás
Nézzünk egy példát, ahol a lambda módosítja a külső változót:
#include <iostream>
int main() {
int counter = 0;
auto increment = [&counter]() {
++counter;
};
increment();
increment();
increment();
std::cout << "counter: " << counter << std::endl;
}
Kimenet:
counter: 3
Itt a lambda minden hívásnál megnöveli a counter változót, mert referenciaként van befogva.
6️⃣ Capture by reference veszélyei
⚠️ Élettartam probléma: ha a lambda egy másik szálon vagy később fut le, és a referenciázott változó már nem él, abból hiba lesz (dangling reference).
Példa:
#include <iostream>
#include <functional>
std::function<void()> makeLambda() {
int x = 42;
return [&x]() {
std::cout << "x: " << x << std::endl; // HIBA: x megszűnik
};
}
int main() {
auto lambda = makeLambda();
lambda(); // undefined behavior!
}
Ezért ha a lambda hosszabb élettartamú (pl. másik szálban fut), érték szerint érdemes capture-ölni.
7️⃣ Összehasonlítás érték vs referencia
Capture by Value [x] |
Capture by Reference [&x] |
|---|---|
| Másolat készül | Referencia kerül be |
| Eredeti változás nem látszik | Eredeti változás látszik |
| Thread-safe | Nem thread-safe (vigyázni kell) |
| Nagy objektumok → drága lehet | Nagy objektumok → olcsó, nincs másolat |
8️⃣ Összetett capture lista
Lehet vegyesen is használni:
auto lambda = [x, &y]() {
// x by value, y by reference
};
xmásolat → nem fog látni változástyreferencia → látni fogja a változást
9️⃣ Gyakorlati példa: algoritmusban használat
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v{1, 2, 3, 4, 5};
int sum = 0;
std::for_each(v.begin(), v.end(), [&sum](int x) {
sum += x;
});
std::cout << "Sum: " << sum << std::endl;
}
Kimenet:
Sum: 15
Itt a sum változót referenciaként fogjuk be, hogy a lambda minden egyes elemnél hozzáadhassa az értéket.
10️⃣ Összefoglalás
Capture by reference előnyei:
✅ Nem kell másolatot készíteni
✅ Módosítható a külső változó
✅ Hatékony nagy objektumoknál
✅ Az aktuális értéket látjuk futáskor
Hátrányai:
⚠️ Vigyázni kell az élettartamra → dangling reference veszély ⚠️ Nem thread-safe ha a külső változót más szál is módosítja ⚠️ Nehéz debuggolni, ha nem világos, mit viszünk be referenciaként
Záró tanács
- Ha olvasni szeretnél → by value
[x]→ biztonságos - Ha módosítani szeretnél → by reference
[&x]→ de figyelj az élettartamra! - Ha lambda hosszú ideig él → inkább by value!
- Ha lambda csak lokálisan, rövid életű → by reference lehet jó.
- lambda capture by reference - Szótár.net (en-hu)
- lambda capture by reference - Sztaki (en-hu)
- lambda capture by reference - Merriam–Webster
- lambda capture by reference - Cambridge
- lambda capture by reference - WordNet
- lambda capture by reference - Яндекс (en-ru)
- lambda capture by reference - Google (en-hu)
- lambda capture by reference - Wikidata
- lambda capture by reference - Wikipédia (angol)