We will discuss the capture in Lambda Function in C++ in detail, covering capture by value, reference, pointers, and functions pointer with code examples. You will gain a comprehensive understanding of variable capture within lambda functions, exploring various scenarios through clear examples.
Capture in Lambda function in C++
When you create a lambda function, you often want to access variables from the enclosing scope. This process is known as variable capture. The common ways to capture variables: by value, by reference, by specifying all variables by value, or by specifying all variables by reference.
- [n]: Capture n by value
- [&n]: Capture n by reference
- [=]: Capture all variables by value
- [&]: Capture all variables by reference
Let’s discuss all aspects of captures in details by lambda function and code examples.
Capture by Value:
You can capture a variable by value in the lambda function. You can use it inside the lambda function but cannot modify it.
In this example, the lambda function captures the variable x by value from the enclosing scope . The lambda retains a copy of the value of x and uses it within the function.
int main() {
int x = 5;
auto lambda = [x]() {
std::cout << "Captured x by value: " << x << std::endl;
};
lambda(); // Outputs: Captured x by value: 5
return 0;
}
NOTE: You can access the value of the variable X inside the lambda function but CANNOT modify it. If you intend to modify it, you need to use the “mutable” keyword, as shown in the code below where the variable x is being modified (incremented by 1).
int main(){
int x = 5;
auto lambda = [x]() mutable {
x++;
std::cout << "Captured x by value: " << x << std::endl;
};
lambda(); // Outputs: Captured x by value: 5
return 0;
}
Capture by Reference
You can capture a variable by reference as in the lambda function. Modification of the variable is allowed inside the lambda function.
Here, the lambda captures the variable y by reference as [&y] from the enclosing scope. This allows the lambda to access and modify the original variable directly.
int main() {
int y = 10;
auto lambda = [&y]() {
std::cout << "Captured y by reference: " << y << std::endl;
y++; // Modify y
};
lambda(); // Outputs: Captured y by reference: 10
std::cout << "Modified y: " << y << std::endl; // Outputs: Modified y: 11
return 0;
}
Capture All Variables by Value
The lambda in this case captures all variables in the enclosing scope (a and b) by value. This is accomplished using the capture-all syntax [=].
int main() {
int a = 3, b = 7;
auto lambda = [=]() {
std::cout << "Captured a and b by value: " << a << ", " << b << std::endl;
};
lambda(); // Outputs: Captured a and b by value: 3, 7
return 0;
}
Capture All Variables by Reference
Capturing all variables by reference is accomplished using the capture-all syntax [&].
This example demonstrates capturing all variables in the enclosing scope (c and d) by reference. The lambda can access and modify these variables within the function body.
int main() {
int c = 15, d = 20;
auto lambda = [&]() {
std::cout << "Captured c and d by reference: " << c << ", " << d << std::endl;
c++; // Modify c
d++; // Modify d
};
lambda(); // Outputs: Captured c and d by reference: 15, 20
std::cout << "Modified c: " << c << ", Modified d: " << d << std::endl;
return 0;
}
Capture Pointer in Lambda C++
Lambda functions can also capture pointers, allowing you to access and manipulate the data they point to.
Here, the lambda captures a pointer ptr by value from the enclosing scope. The captured pointer allows the lambda to access the value pointed to by ptr and use it within the lambda function.
int main() {
int num = 42;
int* ptr = #
auto lambda = [ptr]() {
std::cout << "Value pointed to by ptr: " << *ptr << std::endl;
};
lambda(); // Outputs: Value pointed to by ptr: 42
return 0;
}
Capture Function pointer in Lambda C++
You can capture a function pointer in the capture list of a lambda function. Here, the function pointer ‘fp’ points to the ‘add’ function. You can observe the capture of ‘fp’ as ‘[fp]’ in the lambda.
int add(int a, int b) {
return a + b;
}
int main() {
//function pointer pointing to function add
int (*fp)(int a, int b) = add;
//lambda function access function pointer fp in capture list
auto lambda = [fp]() {
int result = fp(5, 3);
std::cout << "Result of add function: " << result << std::endl;
};
lambda(); // Outputs: Result of add function: 8
return 0;
}
Lambda functions provide a flexible and powerful mechanism to capture variables, and pointers, enhancing the way you structure and interact with your C++ code. By understanding the nuances of variable capture, you can wield the full potential of lambda functions to write cleaner, more efficient, and more expressive code.