0
0
CppComparisonBeginner · 4 min read

Lambda Capture by Value vs Reference in C++: Key Differences and Usage

In C++, lambda capture by value copies variables into the lambda, preserving their values at capture time, while capture by reference lets the lambda access the original variables, reflecting any changes made after capture. Use capture by value to keep a snapshot of variables, and capture by reference to work with their current state.
⚖️

Quick Comparison

This table summarizes the main differences between lambda capture by value and by reference in C++.

AspectCapture by ValueCapture by Reference
Variable AccessCopies variables into lambdaUses original variables by reference
Variable Changes After CaptureNot reflected inside lambdaReflected inside lambda
SafetySafer, no dangling referencesRisk of dangling references if variables go out of scope
PerformanceMay copy large objects (costly)No copy, just reference (efficient)
Use CaseWhen you want a snapshot of valuesWhen you want to modify or observe changes
Syntax Example[x, y][&x, &y]
⚖️

Key Differences

Capture by value means the lambda makes its own copy of the variables it uses. This means the lambda keeps the values as they were when it was created, even if the original variables change later. This is useful when you want to preserve the state at capture time and avoid unexpected side effects.

On the other hand, capture by reference means the lambda uses the original variables directly. Any changes to those variables after the lambda is created will be visible inside the lambda. This allows the lambda to modify or observe the current state of variables, but it can be risky if the variables go out of scope before the lambda is called, causing undefined behavior.

Choosing between these depends on whether you want a stable snapshot of data (by value) or live access to variables (by reference). Also, copying large objects can be costly, so by reference can be more efficient but less safe.

⚖️

Code Comparison

This example shows a lambda capturing variables by value. The lambda prints the copied values even if the originals change later.

cpp
#include <iostream>

int main() {
    int x = 10;
    int y = 20;

    auto lambda_by_value = [x, y]() {
        std::cout << "Inside lambda by value: x = " << x << ", y = " << y << "\n";
    };

    x = 100; // change original variables
    y = 200;

    lambda_by_value();

    return 0;
}
Output
Inside lambda by value: x = 10, y = 20
↔️

Capture by Reference Equivalent

This example shows a lambda capturing variables by reference. The lambda reflects the updated values of the original variables.

cpp
#include <iostream>

int main() {
    int x = 10;
    int y = 20;

    auto lambda_by_ref = [&x, &y]() {
        std::cout << "Inside lambda by reference: x = " << x << ", y = " << y << "\n";
    };

    x = 100; // change original variables
    y = 200;

    lambda_by_ref();

    return 0;
}
Output
Inside lambda by reference: x = 100, y = 200
🎯

When to Use Which

Choose capture by value when you want the lambda to keep a fixed snapshot of variables at the time it is created, avoiding side effects from later changes. This is safer and good for multi-threading or when variables might go out of scope.

Choose capture by reference when you want the lambda to access or modify the current state of variables, reflecting any changes made after capture. Use this when performance matters and you are sure the variables will remain valid while the lambda runs.

Key Takeaways

Capture by value copies variables into the lambda, preserving their state at capture time.
Capture by reference lets the lambda access and modify the original variables directly.
Use capture by value for safety and stable snapshots, especially if variables may change or go out of scope.
Use capture by reference for efficiency and when you need live access to variable changes.
Be careful with capture by reference to avoid dangling references and undefined behavior.