Programación funcional en C++: de lambdas a algoritmos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Programación funcional en C++: de lambdas a composición



La programación funcional (PF) es un paradigma en el que los cálculos se basan en la aplicación de funciones puras, la inmutabilidad de los datos y la ausencia de efectos secundarios. Aunque C++ fue originalmente un lenguaje multiparadigma, sus estándares modernos (C++11/14/17/20) introdujeron potentes herramientas para PF: expresiones lambda, std::function, algoritmos STL, corrutinas e incluso soporte para patrones monádicos. En este artículo, analizaremos cómo escribir código funcional en C++ sin perder rendimiento.



1. Fundamentos del estilo funcional: lambdas y std::function



Las expresiones lambda son el corazón de la PF en C++. Permiten crear funciones anónimas «sobre la marcha», capturando el contexto.



#include <iostream>#include <vector>#include <algorithm>

int main() { std::vector<int> nums = {1, 2, 3, 4, 5}; // Lambda para filtrar números pares auto is_even = [](int x) { return x % 2 == 0; }; // Uso con el algoritmo std::copy_if std::vector<int> evens; std::copy_if(nums.begin(), nums.end(), std::back_inserter(evens), is_even); for (int n : evens) std::cout << n << " "; // 2 4 return 0;}


Puntos clave de las lambdas:

  • Captura — [=] (por valor), [&] (por referencia), [this] (para métodos de clase).
  • Tipo — cada lambda tiene un tipo único, por lo que para pasarla a una función se usa std::function o plantillas.
  • Valor de retorno — se deduce automáticamente, a menos que se especifique lo contrario.


std::function — un envoltorio para objetos invocables (funciones, lambdas, functores). Es útil para almacenar y pasar, pero añade sobrecarga (llamada virtual).



#include <functional>

void apply_twice(std::function<int(int)> f, int x) { std::cout << f(f(x)) << std::endl; // Composición}

int main() { auto square = [](int x) { return x * x; }; apply_twice(square, 3); // (3^2)^2 = 81 return 0;}


2. Algoritmos STL como base de cadenas funcionales



Los algoritmos STL (std::transform, std::copy_if, std::accumulate, etc.) encajan perfectamente con el estilo funcional. No modifican los contenedores directamente, sino que toman iteradores y devuelven resultados.



Ejemplo: filtrado y transformación (map/filter)



#include <numeric>#include <ranges> // C++20

int main() { std::vector<int> data = {1, 2, 3, 4, 5, 6}; // Enfoque clásico (C++11) std::vector<int> filtered; std::copy_if(data.begin(), data.end(), std::back_inserter(filtered), [](int x) { return x > 3; }); std::vector<int> result; std::transform(filtered.begin(), filtered.end(), std::back_inserter(result), [](int x) { return x * 2; }); // Enfoque moderno con ranges (C++20) auto view = data | std::views::filter([](int x) { return x > 3; }) | std::views::transform([](int x) { return x * 2; }); for (int v : view) std::cout << v << " "; // 8 10 12 return 0;}


Plegado (fold) con std::accumulate



#include <numeric>

int main() { std::vector<int> nums = {1, 2, 3, 4}; // Suma con valor inicial 0 int sum = std::accumulate(nums.begin(), nums.end(), 0, [](int a, int b) { return a + b; }); // Producto con valor inicial 1 int prod = std::acc

Blogs

Book Recommendations