C++ Lambda Expressions
What Is a Lambda?
A lambda expression is an anonymous function β a small, inline function you can define on the spot, without giving it a name.
You can store a lambda in a variable, or pass it directly to algorithms like std::sort, std::for_each, or std::transform.
[!NOTE] You can reference the following videos:
Basic Syntax
[capture](parameters) -> return_type {
// body
}
Example:
#include <iostream>
int main() {
auto hello = []() {
std::cout << "Hello, Lambda!" << std::endl;
};
hello(); // prints "Hello, Lambda!"
}
Parts of a Lambda
- Capture list
[ ]β defines what external variables the lambda can access. - Parameters
( )β like regular function parameters. - Return type
->β optional; usually inferred automatically. - Body
{ }β the functionβs code.
Capture Lists Explained
You can use lambdas to access variables from the surrounding scope.
1. Capture by Value [=]
Copies variables into the lambda.
int x = 10;
auto show = [=]() { std::cout << x << std::endl; };
show(); // prints 10
Changes inside wonβt affect the original variable.
2. Capture by Reference [&]
Uses references, allowing modification.
int x = 10;
auto increment = [&]() { x++; };
increment();
std::cout << x << std::endl; // prints 11
3. Capture Specific Variables
int a = 1, b = 2;
auto print = [a, &b]() {
std::cout << a << ", " << b << std::endl;
};
ais copied (by value)bis referenced (by reference)
βοΈ Parameters and Return Values
auto add = [](int a, int b) {
return a + b;
};
std::cout << add(3, 4) << std::endl; // 7
If the return type isnβt clear (like mixing int and double), specify it explicitly:
auto divide = [](int a, int b) -> double {
return (double)a / b;
};
Using Lambdas with STL Algorithms
1. std::for_each β Apply a Function to Each Element
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> nums = {1, 2, 3, 4};
std::for_each(nums.begin(), nums.end(), [](int n) {
std::cout << n * n << " ";
});
// Output: 1 4 9 16
}
2. std::transform β Modify Elements in Place
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> nums = {1, 2, 3, 4};
std::transform(nums.begin(), nums.end(), nums.begin(), [](int n) {
return n * 10;
});
for (int n : nums) std::cout << n << " ";
// Output: 10 20 30 40
}
3. std::sort β Custom Sorting
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> nums = {5, 2, 8, 1};
std::sort(nums.begin(), nums.end(), [](int a, int b) {
return a > b; // sort descending
});
for (int n : nums) std::cout << n << " ";
// Output: 8 5 2 1
}
4. std::count_if β Conditional Counting
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> nums = {1, 2, 3, 4, 5, 6};
int evens = std::count_if(nums.begin(), nums.end(), [](int n) {
return n % 2 == 0;
});
std::cout << "Even numbers: " << evens << std::endl; // 3
}
5. std::remove_if β Filter Elements
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> nums = {1, 2, 3, 4, 5, 6};
nums.erase(
std::remove_if(nums.begin(), nums.end(), [](int n) { return n % 2 == 0; }),
nums.end()
);
for (int n : nums) std::cout << n << " ";
// Output: 1 3 5
}
Stateful (Closure) Lambdas
Lambdas can remember variables captured from the outside:
int count = 0;
auto counter = [&]() {
count++;
return count;
};
std::cout << counter() << std::endl; // 1
std::cout << counter() << std::endl; // 2
Summary
| Concept | Example | Description |
|---|---|---|
| Basic Lambda | [](){} |
No captures or parameters |
| Capture by Value | [=] |
Copies variables |
| Capture by Reference | [&] |
Uses references |
| Parameters | (int x, int y) |
Like normal functions |
| Return Type | -> double |
Optional explicit type |
| In STL | std::sort(v.begin(), v.end(), [](int a,int b){return a<b;}); |
Inline usage |