Lambda Expressions in C++
A lambda expression is a compact way to define an anonymous function (a function without a name) right where it is needed. Introduced in C++11, lambdas make code shorter and more readable — especially when working with STL algorithms.
Basic Syntax
[capture](parameters) -> return_type {
// function body
}
[]— Capture list: which variables from the surrounding scope the lambda can use.()— Parameter list: inputs to the lambda.-> type— Optional return type (often auto-deduced).{ }— Lambda body.
Simplest Lambda
#include <iostream>
using namespace std;
int main() {
auto greet = []() {
cout << "Hello from lambda!" << endl;
};
greet(); // call the lambda
return 0;
}
Output:
Hello from lambda!Lambda with Parameters
auto add = [](int a, int b) {
return a + b;
};
cout << add(3, 7) << endl; // 10
Lambda with Return Type
auto divide = [](double a, double b) -> double {
if (b == 0) return 0;
return a / b;
};
cout << divide(10.0, 4.0) << endl; // 2.5
Capture List
The capture list allows the lambda to use variables from the enclosing scope:
Capture by value ([=]):
int x = 10;
auto showX = [=]() {
cout << "x = " << x << endl; // uses copy of x
};
showX(); // x = 10
Capture by reference ([&]):
int count = 0;
auto increment = [&]() {
count++; // modifies the original
};
increment();
increment();
cout << count << endl; // 2
Capture specific variables:
int a = 5, b = 10;
auto sum = [a, &b]() {
b += a; // a by value, b by reference
};
sum();
cout << b << endl; // 15
Lambda with STL Algorithms
Lambdas shine when used with STL algorithms:
Sorting with custom comparator:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v = {5, 1, 8, 2, 9, 3};
// Sort in descending order
sort(v.begin(), v.end(), [](int a, int b) {
return a > b;
});
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
Output:
9 8 5 3 2 1Using for_each with lambda:
#include <algorithm>
vector<int> nums = {1, 2, 3, 4, 5};
for_each(nums.begin(), nums.end(), [](int n) {
cout << n * n << " ";
});
// Output: 1 4 9 16 25
Filtering with count_if:
vector<int> data = {10, 25, 30, 45, 50, 15};
int countAbove30 = count_if(data.begin(), data.end(), [](int x) {
return x > 30;
});
cout << "Elements above 30: " << countAbove30 << endl; // 2
Mutable Lambda
By default, captured-by-value variables cannot be modified inside the lambda. The mutable keyword allows modification of local copies:
int val = 10;
auto modify = [val]() mutable {
val += 5;
cout << "Inside lambda: " << val << endl; // 15
};
modify();
cout << "Outside: " << val << endl; // 10 — original unchanged
Generic Lambda (C++14)
In C++14, auto can be used as the parameter type to create generic lambdas:
auto multiply = [](auto a, auto b) {
return a * b;
};
cout << multiply(3, 4) << endl; // 12
cout << multiply(2.5, 4.0) << endl; // 10.0
Key Takeaways
- Lambda expressions are anonymous functions defined inline where needed.
- The capture list
[]defines which outer variables are accessible in the lambda. - Capture by value
[=]copies variables; capture by reference[&]gives direct access. - Lambdas work excellently with STL algorithms like
sort,for_each, andcount_if. - Use
mutablewhen needing to modify captured-by-value variables inside the lambda.
