Przechwytywanie w lambdach: przez wartość, referencję, mutable
Świadomie wybieraj klauzule przechwytywania i poznawaj stan lambd
Przechwytywanie w lambdach: przez wartość, referencję, mutable to bezpłatna lekcja C++ Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C++ Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C++ Academy zawiera 4 lekcji w sumie.
Podsumowanie przechwytywania
Klauzula przechwytywania lambdy wymienia zmienne z otaczającego zakresu, z których może ona korzystać. Tryb przechwytywania określa sposób dostępu do każdej zmiennej.
Przechwytywanie przez wartość
Nazwy wymienione bez & są kopiowane podczas tworzenia lambdy. Lambda przechowuje własną kopię.
int n = 5;
auto f = [n]() { return n * 2; };
n = 10;
std::cout << f(); // 10 (captured n was 5)Przechwytywanie przez referencję
Nazwy poprzedzone & są przechowywane jako referencje do zmiennej zewnętrznej. Zmiany są widoczne w obu kierunkach.
int counter = 0;
auto inc = [&counter]() { ++counter; };
inc(); inc();
std::cout << counter; // 2Przechwytywanie domyślne: =
[=] przechwytuje przez wartość wszystko, co jest używane w ciele lambdy. Jest to wygodne, ale może zaskakiwać — przechwytywane są tylko zmienne, do których następuje odwołanie.
int a = 1, b = 2, c = 3;
auto f = [=]() { return a + c; }; // captures a and c (not b)Przechwytywanie domyślne: &
[&] przechwytuje przez referencję wszystko, co jest używane. Należy zachować ostrożność — referencje do zmiennych lokalnych stają się wiszące, jeśli lambda przetrwa zakres.
int n = 0;
auto bad = [&]() { return n; };
return bad; // n dies, lambda danglesŁączenie trybów
Można łączyć przechwytywanie domyślne z jawnym. Poszczególne zmienne służą do zastąpienia trybu domyślnego.
int a = 1, b = 2;
auto f = [=, &b]() { // a by value, b by reference
return a + b;
};Mutowalne lambdy
Zmienne przechwycone przez wartość są wewnątrz lambdy const. Należy dodać mutable, aby lambda mogła modyfikować przechwyconą kopię.
int n = 5;
auto inc = [n]() mutable {
++n;
return n;
};
inc(); inc();
std::cout << n; // 5 (outer unchanged)Przechwytywanie inicjalizujące (C++14)
Można przechwycić wynik wyrażenia pod nową nazwą. Umożliwia to przechwytywanie przez przeniesienie oraz używanie obliczonych wartości początkowych.
auto ptr = std::make_unique<int>(42);
auto f = [p = std::move(ptr)]() {
return *p;
};
// ptr is now empty; p owns the int inside the lambdaPrzechwytywanie this
Wewnątrz funkcji składowej [this] przechwytuje wskaźnik this — wszystkie składowe są dostępne wewnątrz lambdy.
Przechwytywanie *this (C++17)
[*this] kopiuje cały obiekt do lambdy. Jest to przydatne, gdy lambda przetrwa oryginalny obiekt.
Pułapka: przechwytywanie przez referencję i asynchroniczność
Nigdy nie należy przechwytywać zmiennych lokalnych przez referencję w lambdzie wykonywanej asynchronicznie — zmienne lokalne prawdopodobnie przestaną istnieć, zanim lambda zostanie wywołana.
// BUG
int local = 42;
std::async([&local]() { use(local); }); // local dies, lambda danglesSzybkie sprawdzenie
Jaki tryb przechwytywania pozwala lambdzie przejąć własność obiektu std::unique_ptr z zewnętrznego zakresu?
Podsumowanie
Przechwytywanie przez wartość tworzy kopię, a przez referencję — alias. Z przechwytywań domyślnych [=] i [&] należy korzystać ostrożnie. mutable pozwala modyfikować kopie przechwycone przez wartość. Przechwytywanie inicjalizujące (C++14) umożliwia przechwytywanie przez przeniesienie.
Często zadawane pytania
Czy lekcja „Przechwytywanie w lambdach: przez wartość, referencję, mutable” jest bezpłatna?
Tak — pełny tekst „Przechwytywanie w lambdach: przez wartość, referencję, mutable” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C++ Academy, przejdź na CoddyKit PRO. Kurs C++ Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Przechwytywanie w lambdach: przez wartość, referencję, mutable”?
Świadomie wybieraj klauzule przechwytywania i poznawaj stan lambd Ćwiczysz C++ Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C++ Academy?
Nie wymagamy żadnego doświadczenia. C++ Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Przechwytywanie w lambdach: przez wartość, referencję, mutable”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C++ Academy?
Tak. Każda lekcja C++ Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Obiekty funkcyjne i funktory
- Przechwytywanie w lambdach: przez wartość, referencję, mutable
- Generyczne lambdy i domknięcia w C++14
- std::function — wywoływalne obiekty z wymazywaniem typu