A lambda is an unnamed function object written inline: [captures](params) { body }. It's how you pass behaviour to algorithms, threads and callbacks.
Syntax
[capture](parameters) mutable noexcept -> ReturnType { body }
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
auto add = [](int a, int b) { return a + b; }; // return type deduced
std::cout << add(2, 3) << '\n';
std::vector<int> v{5, 2, 8, 1};
std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; }); // descending
for (int x : v) std::cout << x << ' ';
std::cout << '\n';
int threshold = 3;
auto big = std::count_if(v.begin(), v.end(), [threshold](int x) { return x > threshold; });
std::cout << big << '\n';
}5
8 5 2 1
2Captures
| Capture | Meaning |
|---|---|
[] | Nothing captured |
[x] | x by value (a copy taken when the lambda is created) |
[&x] | x by reference |
[=] | Everything used, by value |
[&] | Everything used, by reference |
[=, &x] / [&, x] | Default plus exceptions |
[this] / [*this] | The enclosing object by pointer / by copy (C++17) |
[y = expr] | Init-capture (C++14): new variable, e.g. [p = std::move(ptr)] |
#include <iostream>
int main() {
int n = 1;
auto byVal = [n] { return n; }; // copies n now
auto byRef = [&n] { return n; }; // refers to n
n = 10;
std::cout << byVal() << ' ' << byRef() << '\n';
auto counter = [count = 0]() mutable { return ++count; }; // own state; `mutable` allows changing copies
counter(); counter();
std::cout << counter() << '\n';
}1 10
3Generic and immediately-invoked lambdas
#include <functional>
#include <iostream>
#include <string>
int main() {
auto twice = [](auto x) { return x + x; }; // generic lambda (C++14)
std::cout << twice(21) << ' ' << twice(std::string("ab")) << '\n';
const int config = [] { // IIFE: initialise a const in steps
int v = 0;
for (int i = 1; i <= 4; ++i) v += i;
return v;
}();
std::cout << config << '\n';
std::function<int(int)> fib = [&fib](int k) { // recursive lambda via std::function
return k < 2 ? k : fib(k - 1) + fib(k - 2);
};
std::cout << fib(10) << '\n';
}42 abab
10
55What a lambda really is
The compiler turns each lambda into an unnamed class with an operator() — captured variables become data members. Captureless lambdas also convert to plain function pointers.
#include <iostream>
struct AddN { // roughly what [n](int x) { return x + n; } becomes
int n;
int operator()(int x) const { return x + n; }
};
int main() {
int n = 5;
auto lambda = [n](int x) { return x + n; };
AddN functor{n};
int (*fp)(int) = [](int x) { return x * 2; }; // captureless → function pointer
std::cout << lambda(1) << ' ' << functor(1) << ' ' << fp(4) << '\n';
}6 6 8Why does a by-value capture need mutable to be modified?
What's the type of a lambda?