Closures replace functor classes; the IIFE idiom initializes complex consts in one expression.
const auto table = [] {
std::map<int, std::string> m;
for (int i = 0; i < 8; ++i) m[i] = name(i);
return m;
}(); // IIFE: complex const init
IIFE, init-capture, stateless lambdas, recursion.
Closures replace functor classes; the IIFE idiom initializes complex consts in one expression.
const auto table = [] {
std::map<int, std::string> m;
for (int i = 0; i < 8; ++i) m[i] = name(i);
return m;
}(); // IIFE: complex const init
Generic lambdas and init-captures: move state in, take auto&&, forward on. Lambdas become the default function objects of generic code.
auto task = [buf = std::move(buffer)](auto&& sink) {
sink.write(buf);
};
constexpr by default where possible; *this captured by value for async member work.
Template parameter lists on lambdas, lambdas in unevaluated contexts, and default-constructible stateless lambdas — a lambda type can now be a comparator template argument directly.
auto by_name = [](const auto& a, const auto& b){ return a.name < b.name; };
std::set<Person, decltype(by_name)> s; // no constructor arg needed
Deducing this enables natural recursion (the lambda names itself); static operator() removes the unused this from stateless call operators.
auto fib = [](this auto self, int n) -> long {
return n < 2 ? n : self(n - 1) + self(n - 2);
};
Stable feature-wise; reflection can inspect closure types, but day-to-day lambda idioms are considered finished.
Nothing in flight that changes lambda guidance.
C++26 per the final working draft; C++29 rows are proposals and direction, not adopted features.