C++ Lambda Functions
A lambda is a small function without a name, written right where it is needed. Lambdas are most often passed to the algorithms of the standard library, such as sort and count_if, to say how to compare or what to count.
The syntax
[capture](parameters) { body }#include <iostream>
int main() {
auto square = [](int x) { return x * x; };
auto greet = [](const char* name) { std::cout << "Hi, " << name << "\n"; };
std::cout << square(7) << "\n";
greet("Asha");
return 0;
}49 Hi, Asha
The return type is worked out from the return statement. A lambda stored in an auto variable can be called like any function.
Lambdas with algorithms
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<int> nums = {5, 3, 8, 1, 9, 2};
std::sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; }); // largest first
for (int n : nums) std::cout << n << " ";
std::cout << "\n";
int evens = std::count_if(nums.begin(), nums.end(), [](int n) { return n % 2 == 0; });
std::cout << evens << " even numbers\n";
std::vector<std::string> words = {"pear", "fig", "banana"};
std::sort(words.begin(), words.end(),
[](const std::string& a, const std::string& b) { return a.size() < b.size(); });
for (const auto& w : words) std::cout << w << " ";
std::cout << "\n";
return 0;
}9 8 5 3 2 1 2 even numbers fig pear banana
Captures
The square brackets list the variables from around the lambda that it may use:
[limit]copieslimitinto the lambda (capture by value);[&total]lets the lambda use and changetotalitself (capture by reference);[=]copies everything used,[&]references everything used.
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> marks = {45, 72, 88, 39, 91};
int passMark = 50;
int passed = std::count_if(marks.begin(), marks.end(), [passMark](int m) { return m >= passMark; });
std::cout << passed << " passed\n";
int total = 0;
std::for_each(marks.begin(), marks.end(), [&total](int m) { total += m; });
std::cout << "total " << total << "\n";
return 0;
}3 passed total 335
Prefer listing the captures explicitly: it shows exactly what the lambda depends on. Be careful with references: a lambda that outlives a variable it captured by reference refers to nothing valid.
Storing lambdas
auto holds a lambda most efficiently. When a variable or parameter must accept any function with a given shape, use std::function<int(int)> from the functional header.
When to use a lambda
Use a lambda when a small piece of behaviour is needed in one place: a sort order, a filter, a callback for a button. If the same logic is needed in several places, or it grows beyond a few lines, give it a name as an ordinary function. Code reads best when lambdas stay short enough to understand at a glance.
Practice exercises
- Sort a vector of numbers by their last digit using a lambda.
- Count the words longer than a length the user types, capturing it in the lambda.
- Use
std::for_eachwith a lambda that captures a counter by reference to count the negative numbers in a vector.