Lección 11 · 11 de 20
Lambdas y capturas · C++
Escriba funciones en el sitio con las lambdas de C++: ordene tareas, capture variables por valor o por referencia y use mutable y auto.

Una lambda es una función sin nombre escrita justo donde se necesita: [capturas](parámetros) { cuerpo }. byPriority compara dos tareas por prioridad y se pasa a std::stable_sort, que las ordena de mayor a menor y, a igual prioridad, respeta el orden original («Fix login» antes que «Review PR»).
Entre corchetes van las capturas, las variables de fuera que la lambda puede usar. [budget, &planned] captura budget por valor (una copia, que dentro no se puede cambiar) y planned por referencia, con &: cuando fits suma horas, cambia la variable de main. Así se planifican tareas hasta llenar las 4 horas, y «Write docs» se queda para más tarde.
Una lambda que captura por valor no puede modificar su copia, salvo que se marque `mutable`. nextTicket lleva su propio contador, que empieza en 100 y da 101 y 102, mientras el ticket de main sigue en 100. También existen [=] (todo por valor) y [&] (todo por referencia), aunque es más claro nombrar cada variable.
Con auto en los parámetros se obtiene una lambda genérica, que funciona como una plantilla: twice(21) da 42 y twice(std::string("ha")) da «haha». Cada lambda tiene un tipo propio que solo conoce el compilador; por eso se guarda en una variable auto.
Código · main.cpp
#include <algorithm>#include <iostream>#include <string>#include <vector>struct Task { std::string title; int priority; double hours; };int main() { std::vector<Task> tasks = {{"Fix login", 3, 2.5}, {"Write docs", 1, 4}, {"Release", 5, 1}, {"Review PR", 3, 0.5}}; // A lambda is a function written in place: [captures](parameters) { body }. auto byPriority = [](const Task& a, const Task& b) { return a.priority > b.priority; }; std::stable_sort(tasks.begin(), tasks.end(), byPriority); // [budget] copies the variable; [&planned] works on the original. double budget = 4.0, planned = 0; auto fits = [budget, &planned](const Task& t) { if (planned + t.hours > budget) return false; planned += t.hours; return true; }; for (const Task& t : tasks) std::cout << (fits(t) ? "[today] " : "[later] ") << t.title << " (p" << t.priority << ")\n"; std::cout << "Planned: " << planned << " of " << budget << " hours\n"; // mutable lets a lambda change its own copy of a captured value. int ticket = 100; auto nextTicket = [ticket]() mutable { return ++ticket; }; int a = nextTicket(), b = nextTicket(); std::cout << "Tickets " << a << " and " << b << ", but ticket is still " << ticket << "\n"; auto twice = [](auto x) { return x + x; }; // generic lambda: auto parameter std::cout << twice(21) << " " << twice(std::string("ha")) << "\n";}Salida · c++ -std=c++17 main.cpp -o main && ./main
[today] Release (p5) [today] Fix login (p3) [today] Review PR (p3) [later] Write docs (p1) Planned: 4 of 4 hours Tickets 101 and 102, but ticket is still 100 42 haha
Para recordar
- Una lambda es
[capturas](parámetros) { cuerpo }. [x]copia la variable;[&x]trabaja con la original.mutabledeja cambiar la copia capturada por valor.- Con parámetros
auto, la lambda es genérica. - Las lambdas son ideales para pasar criterios a
sorty a los algoritmos.
Ejercicio
Cambie el presupuesto a 3 horas y añada una lambda byHours que ordene por horas, de menos a más. Planifique con ese orden y compare cuántas tareas caben ahora.