C++ Lambda
C++ Lambda Functions are one of the most powerful features introduced in C++11. They allow you to write anonymous functions directly in your code, making your programs more concise and expressive. Lambdas are particularly useful when you need a short, one-off function that doesn’t justify a separate function declaration or definition.
In simple terms, a lambda function is a function that is defined directly in the place where it’s invoked, typically used for short-term tasks. Lambdas are useful for tasks like sorting, filtering, or modifying data without the need for creating separate function definitions.
The syntax of a lambda function is:
[ capture ] ( parameters ) -> return_type { body }
Let’s break down the syntax of a C++ lambda function and understand each part:
[ capture ] ( parameters ) -> return_type { body }
[ capture ]
The capture clause specifies the variables from the outer scope that the lambda will use. The capture clause can be:
[x]
(captures x
by value)[&x]
(captures x
by reference)[=]
(captures all variables used in the lambda by value)[&]
(captures all variables by reference)( parameters )
The parameters part of the lambda is like the parameters of a regular function. You can specify the types of parameters or omit them for type inference.
-> return_type
The return type is optional. If not specified, C++ will automatically deduce it. If the return type can’t be deduced automatically, you should specify it.
{ body }
The body of the lambda contains the code that runs when the lambda is called. It can use the captured variables from the outer scope and take parameters, just like a regular function.
Here’s a simple example of using a lambda to add two numbers:
#include <iostream>
using namespace std;
int main() {
// Define a lambda that adds two integers
auto add = [](int a, int b) { return a + b; };
// Use the lambda
cout << "Sum: " << add(5, 3) << endl; // Output: Sum: 8
return 0;
}
Explanation:
add
takes two integers a
and b
and returns their sum.auto
keyword is used to infer the type of the lambda.Output:
Sum: 8
One of the key features of lambda functions is the ability to capture variables from the surrounding scope. Let's see an example where a lambda captures variables by reference and by value.
#include <iostream>
using namespace std;
int main() {
int x = 10, y = 20;
// Capture x by value and y by reference
auto add = [x, &y](int z) {
return x + y + z;
};
// Modify y to demonstrate capturing by reference
y = 30;
cout << "Result: " << add(5) << endl; // Output: Result: 45
return 0;
}
Explanation:
x
by value and y
by reference.y
is modified after the lambda is defined, the lambda uses the updated value of y
because it captures by reference.Output:
Result: 45
Sometimes, a lambda function doesn't need to take any parameters. Here’s an example of a lambda that just prints a message.
#include <iostream>
using namespace std;
int main() {
// Define a lambda with no parameters
auto greet = []() { cout << "Hello, Lambda!" << endl; };
// Call the lambda
greet(); // Output: Hello, Lambda!
return 0;
}
Explanation:
greet
takes no parameters and simply prints a message to the console.Output:
Hello, Lambda!
If the return type of the lambda function is not obvious, you can explicitly specify it using the ->
syntax.
#include <iostream>
using namespace std;
int main() {
// Lambda with an explicit return type
auto multiply = [](int a, int b) -> int { return a * b; };
// Call the lambda
cout << "Product: " << multiply(4, 5) << endl; // Output: Product: 20
return 0;
}
Explanation:
multiply
takes two integers and returns their product.int
is specified explicitly, although C++ could deduce it in this case.Output:
Product: 20
Lambdas are commonly used with standard library algorithms to perform tasks like sorting, filtering, or transforming data. Here's an example using std::sort
with a lambda to sort a vector in descending order:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vec = {5, 1, 8, 3, 7};
// Sort the vector in descending order using a lambda
sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; });
// Print the sorted vector
for (int num : vec) {
cout << num << " ";
}
return 0;
}
Explanation:
[](int a, int b) { return a > b; }
is used as the comparison function for std::sort
.vec
in descending order.Output:
8 7 5 3 1
Lambdas in C++ can do much more than simple function-like tasks. Some advanced features include:
Capturing this
: You can capture the this
pointer inside member functions to access member variables and functions of the object.
class MyClass {
public:
int x = 5;
void print() {
auto lambda = [this]() { cout << x << endl; };
lambda(); // Output: 5
}
};
auto getMultiplier(int factor) {
return [factor](int x) { return x * factor; };
}
auto multiplyBy3 = getMultiplier(3);
cout << multiplyBy3(5); // Output: 15