In C, the lambda capture clause controls how external variables are introduced into the lambda function through values, references, or default patterns. 1. The capture list is at the beginning of the lambda expression and is used to capture variables in the external scope for internal use of the lambda. 2. Capture through value ([var]) will copy the variable. Modification in the lambda will not affect the original variable. If you need to modify the copy, you need to use the mutable keyword. 3. By reference capture ([&var]) allows lambda to directly modify the original variable, but there is a risk of dangling references. 4. Default capture mode [=] automatically captures all used variables by value, [&] automatically captures by reference, but should be used with caution to avoid potential errors. 5. You can use a mix of specific captures with default captures, such as [=, &x] or [&, x], but the same variable cannot be captured repeatedly and may affect the readability of the code. 6. When choosing a capture method, you should weigh performance and behavior based on your needs to avoid unnecessary copying and misuse of default capture.
In C , a lambda capture clause determines how variables from the surrounding scope are made available inside a lambda function. It's the part of the lambda expression enclosed in square brackets []
, and it controls whether those variables are captured by value, by reference, or not at all.

What the Capture Clause Does
The capture clause sits at the very beginning of a lambda expression. Its job is to "capture" (ie, bring into the lambda's scope) variables that exist outside the lambda but are needed for its execution. Without a proper capture clause, you won't be able to access external variables inside your lambda body.

Capturing Variables by Value ( [var]
)
When you capture a variable by value, a copy of that variable is stored inside the lambda. This means changes made inside the lambda do not affect the original variable.
For example:

int x = 10; auto func = [x]() { std::cout << x; }; x = 20; func(); // Outputs 10, not 20
Here, x
is captured by value, so even after changing x
to 20, the lambda still holds the original value (10) when it was created.
If you want to modify the captured copy inside the lambda, you need to add the mutable
keyword:
auto func = [x](int y) mutable { x = y; std::cout << x; };
Now, x
can be changed within the lambda — but again, only the copy.
Capturing Variables by Reference ( [&var]
)
Capturing by reference gives the lambda direct access to the original variable. Any modifications inside the lambda will affect the original variable.
Example:
int x = 10; auto func = [&x]() { x = 30; }; func(); std::cout << x; // Outputs 30
This is useful when you want to modify state outside the lambda. But it also introduces risk — if the lambda outlives the variable it references, you end up with a dangling reference.
Default Capture Modes: [=]
and [&]
Instead of listing each variable, you can use default capture modes:
-
[=]
captures all used variables by value -
[&]
captures all used variables by reference
These are convenient but should be used carefully. For instance:
int a = 1, b = 2; auto func = [=]() { std::cout << ab; };
Here, both a
and b
are captured by value automatically.
Similarly:
auto func = [&](int x) { b = x; };
In this case, any referenced variable (like b
) will be captured by reference.
Using default captures can sometimes hide subtle bugs, especially when dealing with long-lived lambdas or complex scopes.
Mixing Specific and Default Captures
You can combine specific and default captures in one clause. For example:
-
[=, &x]
captures everything by value, but capturesx
by reference -
[&, x]
captures everything by reference, but capturesx
by value
Just note that once you specify a default capture, you can't re-capture any variable in the same clause. Also, mixing them can make code harder to read unless done intentionally.
A few points to remember:
- You can't have both
[=, x]
and[&, x]
in the same capture list. - The order doesn't matter —
[x, =]
is the same as[=, x]
.
When to Use Which?
Choosing between capture by value or reference depends on what you're trying to achieve:
- Use capture by value when you want a snapshot of the variable at the time the lambda is created.
- Use capture by reference when you need to reflect changes made inside the lambda back to the original variable.
- Be cautious with
[=]
and[&]
— they're powerful but can lead to unintended behavior if misused.
Also, avoid capturing large objects by value unless necessary — copying them may impact performance.
So yes, lambda capture certificates are pretty straightforward once you understand how they work, but easy to misuse if you're not paying attention.
The above is the detailed content of What is a lambda capture clause in C ?. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

The main difference between Java and other programming languages ??is its cross-platform feature of "writing at once, running everywhere". 1. The syntax of Java is close to C, but it removes pointer operations that are prone to errors, making it suitable for large enterprise applications. 2. Compared with Python, Java has more advantages in performance and large-scale data processing. The cross-platform advantage of Java stems from the Java virtual machine (JVM), which can run the same bytecode on different platforms, simplifying development and deployment, but be careful to avoid using platform-specific APIs to maintain cross-platformity.

C is widely used in the fields of game development, embedded systems, financial transactions and scientific computing, due to its high performance and flexibility. 1) In game development, C is used for efficient graphics rendering and real-time computing. 2) In embedded systems, C's memory management and hardware control capabilities make it the first choice. 3) In the field of financial transactions, C's high performance meets the needs of real-time computing. 4) In scientific computing, C's efficient algorithm implementation and data processing capabilities are fully reflected.

Reducing the use of global variables in C can be achieved by: 1. Using encapsulation and singleton patterns to hide data and limit instances; 2. Using dependency injection to pass dependencies; 3. Using local static variables to replace global shared data; 4. Reduce the dependence of global variables through namespace and modular organization of code.

The main differences between C# and C are memory management, polymorphism implementation and performance optimization. 1) C# uses a garbage collector to automatically manage memory, while C needs to be managed manually. 2) C# realizes polymorphism through interfaces and virtual methods, and C uses virtual functions and pure virtual functions. 3) The performance optimization of C# depends on structure and parallel programming, while C is implemented through inline functions and multithreading.

In C, the bit field is a structure member that specifies the number of bits, used to save memory and directly manipulate hardware. Example: structMyStruct{inta:2;intb:5;intc:1;}. The advantage of bit domains is memory savings, but there are cross-platform issues, access restrictions and assignments that require caution. Example of usage: structStateMachine{unsignedintpower:1;unsignedintmode:2;unsignedinterror:1;}. Performance recommendations include arranging bit fields by size, avoiding overuse and adequate testing.

C is not dead, but has flourished in many key areas: 1) game development, 2) system programming, 3) high-performance computing, 4) browsers and network applications, C is still the mainstream choice, showing its strong vitality and application scenarios.

The syntax of the trigonometric operator in C is condition?expression1:expression2, which is used to select and execute different expressions according to the condition. 1) Basic usage example: intmax=(x>y)?x:y, used to select the larger value in x and y. 2) Example of nested usage: intresult=(a>0&&b>0)?a b:(a==0||b==0)?a*b:a-b, used to perform different operations according to different conditions. 3) Error handling example: std::stringerrorMessage=(errorCode==0)?"Successful&quo

The usage of logical non-operator! in C includes: 1) Basic usage: inverse the Boolean value; 2) Conditional judgment: simplify the code, such as checking whether the container is empty; 3) Loop control: processing elements that do not meet the conditions; 4) Function return value processing: determine whether the operation has failed. Pay attention to potential pitfalls such as pointer processing and operator priority when using!, but it can help write more concise and efficient code.
