lambda capture by value

Üdvözlöm, Ön a lambda capture by value szó jelentését keresi. A DICTIOUS-ban nem csak a lambda capture by value szó összes szótári jelentését megtalálod, hanem megismerheted az etimológiáját, a jellemzőit és azt is, hogyan kell a lambda capture by value szót egyes és többes számban mondani. Minden, amit a lambda capture by value szóról tudni kell, itt található. A lambda capture by value szó meghatározása segít abban, hogy pontosabban és helyesebben fogalmazz, amikor beszélsz vagy írsz. Alambda capture by value és más szavak definíciójának ismerete gazdagítja a szókincsedet, és több és jobb nyelvi forráshoz juttat.

Főnév

lambda capture by value (tsz. lambda capture by values)

  1. (informatika) A lambda függvények (lambda expressions) a C++ egyik modern és erőteljes eszközei. Lehetővé teszik, hogy névtelen függvényeket definiáljunk közvetlenül ott, ahol szükség van rájuk – például egy algoritmusban, egy callback-ben vagy egy másik függvény paramétereként.

Egy lambda formális szintaxisa:

(parameter_list) -> return_type { body }

Ebben a szintaxisban a capture rész az ún. capture list vagy befogási lista. Ez határozza meg, hogy a lambda milyen külső változókat (amelyek a lambda definíciós helyén léteznek) “visz magával” a belsejébe, és hogyan.

Két alapvető mód van erre:

  • érték szerint (by value) → másolatot készít
  • referencia szerint (by reference) → hivatkozást visz magával

Most az érték szerinti befogást fogjuk részletesen vizsgálni.



1️⃣ Mi az a capture by value?

Amikor érték szerint fogsz be egy változót, akkor a lambda másolatot készít az aktuális értékéről abban a pillanatban, amikor a lambdát létrehozod.

Ez azt jelenti, hogy:

  • a lambda belsejében a változó egy saját példányon fog élni
  • a lambda belsejében az eredeti változó további módosításai nem fognak látszani
  • a lambda belsejében a befogott érték nem írható át (alapértelmezetten const lesz)

Szintaxis:

   // csak az 'x' változót fogjuk be érték szerint
   // minden külső változót érték szerint fogunk be

2️⃣ Példa: egyszerű capture by value

#include <iostream>

int main() {
    int x = 10;

    auto lambda = () {
        std::cout << "x inside lambda: " << x << std::endl;
    };

    x = 20;

    lambda();  // Mi lesz az eredmény?
}

Kimenet:

x inside lambda: 10

Magyarázat:

  • A azt jelenti, hogy a lambda 10-es értékkel másolta be az x-et, amikor a lambdát létrehoztuk.
  • A későbbi x = 20; módosítás a lambdán belül nem fog látszani, mert az a lambda példányába másolatként bekerült x-re nincs hatással.



3️⃣ Globális capture by value

A szintaxis azt jelenti, hogy minden használt külső változót érték szerint fogunk be:

#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: 5, y: 8

Miért? A lambda létrehozásakor x és y aktuális értékei kerültek másolatként a lambda példányába. A későbbi módosítás nem látszik.



4️⃣ Miért hasznos az érték szerinti befogás?

  • Biztonságos → nem kell aggódni, hogy a lambda élettartama alatt a külső változó időközben módosul.
  • Egyszerű → másolat készül, ezért a lambda saját példányban “tárolja” az adatot.
  • Thread-safe → ha a lambda egy másik szálban fut, a befogott érték stabil marad.



5️⃣ Módosíthatjuk-e a capture by value változót a lambdán belül?

Alapértelmezetten nem – mert a lambda belsejében a befogott érték const lesz.

Példa:

#include <iostream>

int main() {
    int x = 5;

    auto lambda = () {
        x = 10;  // HIBA! x const
    };

    lambda();
}

Fordítási hiba: x const.



6️⃣ mutable kulcsszó használata

Ha azt szeretnéd, hogy a lambda belsejében az érték szerinti befogott változó módosítható legyen, használhatod a mutable kulcsszót:

#include <iostream>

int main() {
    int x = 5;

    auto lambda = () mutable {
        x = 10;
        std::cout << "x in lambda: " << x << std::endl;
    };

    lambda();

    std::cout << "x outside: " << x << std::endl;
}

Kimenet:

x in lambda: 10
x outside: 5

Mi történik?

  • A lambda saját példányon másolatot készített x-ről.
  • A mutable engedélyezi, hogy ezt a másolatot a lambda belsejében módosítsuk.
  • Az eredeti x a lambda kívül nem változott meg.



7️⃣ Capture by value → lifetime biztonság

Ha egy lokális változót akarsz befogni, capture by value védi meg a lambdát a dangling reference hibától.

Példa:

#include <iostream>
#include <functional>

std::function<void()> makeLambda() {
    int x = 42;

    return () {
        std::cout << "x: " << x << std::endl;
    };
}

int main() {
    auto lambda = makeLambda();
    lambda();  // x még él, mert by value volt befogva!
}

Ha itt &x-el (referenciával) fogtuk volna be, a makeLambda() után x megszűnne → dangling reference.



8️⃣ Capture by value + move-only típusok

C++14-től kezdve capture listában lehet move-olni is változót:

auto ptr = std::make_unique<int>(42);

auto lambda = () {
    std::cout << "p: " << *p << std::endl;
};

Itt p a lambda belsejébe move-olódik, így nem kell shared_ptr-t használnod, ha az ownership a lambdához kerül.



9️⃣ Összegzés

Capture by value előnyei:

Stabil → nem változik, ha a külső változó módosul ✅ Biztonságos → nem lógó referencia ✅ Thread-safe → saját példány ✅ Egyszerű formában tömeges capture

Hátrányai:

⚠️ Másolási költség → ha nagy objektumot fogsz be, költséges lehet ⚠️ Alapértelmezésben nem módosítható (mutable kell hozzá)



10️⃣ Összefoglaló példa

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v{1, 2, 3, 4, 5};
    int factor = 2;

    std::for_each(v.begin(), v.end(), (int x) {
        std::cout << x * factor << " ";
    });

    std::cout << std::endl;
}

Kimenet:

2 4 6 8 10

Itt factor érték szerint van befogva → biztosak lehetünk benne, hogy a for_each ciklus közben a factor értéke nem változik.



Záró gondolat

A capture by value a lambda egyik leghasznosabb eszköze:

  • garantálja a stabil adatot
  • megelőzi a hibás referenciákat
  • egyszerű és intuitív
  • mutable segítségével belső állapotkezelést is lehet vele csinálni.

Fontos figyelembe venni:

  • mikor akarod fixálni a külső értéket → by value
  • mikor akarsz frissített értéket látni → by reference