Lambda Capture Clause in C++
Last Updated :
05 Feb, 2024
In C++, lambda expressions were introduced after C++ 11 and allowed users to create a small inline function directly without declaring functions explicitly. In this article, we will discuss how we can use capture clauses in Lambda expressions to access variables from the enclosing scope of the expressions.
Before exploring the Lambda Capture clauses make sure you are familiar with Lambda Expressions in C++.
Lambda Capture Clauses in C++
The general syntax for a lambda expression is as follows:
[ capture_clause ] (parameters) -> return-type
{
definition of method
}
Here, capture clauses are defined inside the square brackets[].
Capture Clauses in lambda expressions determine how the external variables are accessed from the lambda expression. The capture clauses allow the lambda function to capture external variables and use them inside the lambda body.
There are three ways to capture external variables using the Lambda Capture clauses
- Capture by reference
- Capture by value
- Capture by both reference and value (mixed capture)
Note: A lambda with an empty capture clause [ ] can only access variables which are local to it.
Examples of Lambda Captures
Example 1: Capture Values by Reference
In the following example, we will see how we can capture an external variable by reference so that the lambda function can modify the original variable.
C++
// C++ Program to Demonstrate Lambda Function capturing
// variable by reference
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec = { 10, 20, 30, 40, 50 };
cout << "Original vector before applying lambda "
"function: ";
for (int num : vec) {
cout << num << " ";
}
cout << endl;
// Capture vector values by reference using capture
// clauses
auto lambda = [&vec]() {
cout
<< "Vector values inside the lambda function: ";
for (int& num : vec) {
num *= 10;
cout << num << " ";
}
cout << endl;
};
// Call the lambda function
lambda();
// Print the original vector
// You will observe that the values of the original
// vector will be changed
cout << "Original vector after applying lambda "
"function: ";
for (int num : vec) {
cout << num << " ";
}
return 0;
}
OutputOriginal vector before applying lambda function: 10 20 30 40 50
Vector values inside the lambda function: 100 200 300 400 500
Original vector after applying lambda function: 100 200 300 400 500
Example 2: Capture Values by Value
In the following example we will see how we can capture an external variable by value, which will create a copy of each variable inside the lambda function and the original value won't be affected.
C++
// C++ Program to Demonstrate Lambda Function Capturing
// Vector Values by Value
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec = { 10, 20, 30, 40, 50 };
// Capture vector values by value using capture clauses
auto lambda = [vec]() {
cout
<< "Vector values inside the lambda function: ";
for (int num : vec) {
num *= 10; // Make changes in the captured
// vector values
cout << num << " ";
}
cout << endl;
};
lambda(); // Call the lambda function
// Print the original vector
// You will observe no change in the original vector
// values as they were captured via values
cout << "Original vector after applying lambda "
"function: ";
for (int num : vec) {
cout << num << " ";
}
return 0;
}
OutputVector values inside the lambda function: 100 200 300 400 500
Original vector after applying lambda function: 10 20 30 40 50
Example 3: Capture Values by both Reference and Value(Mixed)
In the following example, we will see how we can capture multiple external variables by both value and reference present outside the scope of the lambda function.
C++
// C++ Program to Demonstrate Lambda Function Capturing
// Vector Values by Reference and Value
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec1 = { 10, 20, 30, 40, 50 };
vector<int> vec2 = { 1, 2, 3, 4, 5 };
cout << "Original vectors before applying lambda "
"function:"
<< endl;
cout << "Values of vector 1: ";
for (int num : vec1) {
cout << num << " ";
}
cout << endl;
cout << "Values of vector 2: ";
for (int num : vec2) {
cout << num << " ";
}
cout << endl;
cout << endl;
// Capture vector 1 values by reference and vector 2
// values by value
auto lambda = [&vec1, vec2]() {
cout << "Vector values inside the lambda function:"
<< endl;
cout << "Values of vector 1: ";
for (int& num : vec1) {
num *= 10; // Make changes in the captured
// vector1 values
cout << num << " ";
}
cout << endl;
cout << "Values of vector 2: ";
for (int num : vec2) {
num *= 10; // Make changes in the captured
// vector2 values
cout << num << " ";
}
cout << endl;
};
lambda(); // Call the lambda function
cout << endl;
cout << "Original vectors after applying lambda "
"function:"
<< endl;
cout << "Values of vector 1: ";
for (int num : vec1) {
cout << num << " ";
}
cout << endl;
cout << "Values of vector 2: ";
for (int num : vec2) {
cout << num << " ";
}
return 0;
}
Output
Original vectors before applying lambda function:
Values of vector 1: 10 20 30 40 50
Values of vector 2: 1 2 3 4 5 Vector values inside the lambda function:
Values of vector 1: 100 200 300 400 500
Values of vector 2: 10 20 30 40 50 Original vectors after applying lambda function:
Values of vector 1: 100 200 300 400 500
Values of vector 2: 1 2 3 4 5
In the following example, vector 1 was passed as a reference, and vector 2 was passed as a value. You can observe that inside the lambda function, the values of both vectors were changed as their values were captured by the Capture clauses. But outside the lambda function, the original value of vector 1 was changed as it was passed via reference but the original values of vector 2 remained the same as it was passed by value.
Conclusion
In the following article, we have discussed how we can use capture clauses along with the lambda expressions in C++. We have discussed various ways through which we can capture external variables in the lambda function which are outside its scope. Please note that if you capture values by reference then the changes will be made to the original data. If you only want to change the values inside the lambda function then use the capture-by-value method so that the original values won't be affected.
Similar Reads
How to use C++ Lambdas with Capture Clauses?
In C++, lambda expressions provide a convenient way to create one-liner functions. One of the key features of lambdas is their ability to capture variables from their surrounding scope by using capture clauses. This allows lambdas to access and modify variables from the outer scope, even after the l
3 min read
How to Capture Pairs in Lambda Expression in C++?
In C++, lambda expressions provide an easy way to define anonymous functions inline. They also allow these inline functions to capture some variables from the surrounding scope. In this article, we will learn how to capture pairs in lambda functions in C++ Capture Pairs in Lambda Expressions in C++W
2 min read
Recursive lambda expressions in C++
A recursive lambda expression is the process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. Using a recursive algorithm, certain problems can be solved quite easily. Examples of such problems are Towers of Ha
8 min read
How to Capture std::vector in Lambda Function?
In C++, lambda functions allow users to define an inline function anywhere in the program. They are also able to capture the objects from outside its definition. In this article, we will look at how to capture a std::vector object in lambda functions in C++. Capture std::vector in Lambda FunctionTo
2 min read
How to Create a Thread in C++?
A thread is a basic element of multithreading which represents the smallest sequence of instructions that can be executed independently by the CPU. In this article, we will discuss how to create a thread in C++. How to Create a Thread in C++?In C++, the std::thread is a class template that is used t
2 min read
How to Create Deque of List in C++?
In C++, deque (double-ended queue) is a linear data structure that allows insertion and deletion at both ends. A list is a sequential container that implements a doubly linked list to store the data in non-contiguous storage. In this article, we will learn how to create a deque of a list in C++. Exa
2 min read
count_if() in C++ STL
count_if() function returns the number of elements in a range that satisfy the condition. Syntax: template <class InputT, class UnaryPredicate> typename iterator_traits <InputT> :: difference_type count_if(InputT first, InputT last, UnaryPredicate p); Examples: Input: 0 1 2 3 4 5 6 7 8 9
2 min read
When to Prefer Lambda Expressions over Functors in C++?
In C++, lambda expressions and functors (function objects) both are used for defining anonymous or named functions in C++. In this article, we will learn when to use a lambda expression instead of a functor in C++. When to Prefer Lambda instead of Functors?Prefer to use a lambda expression instead o
4 min read
Comparator Class in C++ with Examples
Comparator Classes are used to compare the objects of user-defined classes. In order to develop a generic function use template, and in order to make the function more generic use containers, so that comparisons between data can be made. Syntax C/C++ Code class comparator_class { public: // Comparat
5 min read
std::greater in C++ with Examples
The std::greater is a functional object which is used for performing comparisons. It is defined as a Function object class for the greater-than inequality comparison. This can be used for changing the functionality of the given function. This can also be used with various standard algorithms such as
2 min read