Programación funcional en C++: de la A a la Z — guía práctica

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 la A a la Z



Muchos desarrolladores familiarizados con Python o JavaScript están acostumbrados a las potentes herramientas de programación funcional: lambdas, map, filter, reduce. Pero, ¿sabías que C++ ofrece capacidades igualmente flexibles para el estilo funcional? En este artículo, exploraremos la programación funcional en C++ desde los conceptos básicos hasta las técnicas avanzadas. Aprenderás a escribir código más conciso, seguro y expresivo utilizando las características modernas de C++11/14/17.



1. Fundamentos del enfoque funcional: expresiones lambda y std::function



La programación funcional en C++ comienza con las expresiones lambda. Permiten crear funciones anónimas directamente en el punto de uso. La sintaxis de una lambda es simple:



// Lambda básicaauto sum = [](int a, int b) -> int { return a + b; };std::cout << sum(5, 3); // 8

// Lambda con captura de variablesint multiplier = 3;auto multiply = [multiplier](int x) { return x * multiplier; };std::cout << multiply(7); // 21


La característica clave de las lambdas es la captura del contexto. Puedes capturar variables por valor ([=]), por referencia ([&]) o de forma combinada. Esta es la base de los closures, que son el fundamento del estilo funcional.



Para almacenar y pasar lambdas se utiliza std::function, un envoltorio polimórfico para objetos invocables:



#include <functional>

std::function<int(int, int)> operation;

operation = [](int a, int b) { return a + b; };std::cout << operation(10, 20); // 30

operation = [](int a, int b) { return a * b; };std::cout << operation(10, 20); // 200


Consejo: Usa auto para lambdas si no necesitas almacenarlas como tipo. std::function añade una pequeña sobrecarga, por lo que debe usarse solo cuando se requiere polimorfismo.



2. Algoritmos STL: map, filter, reduce hechos a mano



En C++ no hay funciones integradas map, filter, reduce como en Python, pero STL proporciona potentes algoritmos que las reemplazan. Veamos los principales:



2.1. Map — transformación de elementos

En lugar de map, usa std::transform:



#include <algorithm>#include <vector>

std::vector<int> numbers = {1, 2, 3, 4, 5};std::vector<int> squares(numbers.size());

std::transform(numbers.begin(), numbers.end(), squares.begin(), [](int n) { return n * n; });// squares: {1, 4, 9, 16, 25}


2.2. Filter — filtrado por condición

El análogo de filter es std::copy_if o std::remove_if (con posterior eliminación):



std::vector<int> numbers = {1, 2, 3, 4, 5, 6};std::vector<int> evens;

std::copy_if(numbers.begin(), numbers.end(), std::back_inserter(evens), [](int n) { return n % 2 == 0; });// evens: {2, 4, 6}


2.3. Reduce — reducción de la colección

Para reduce usa std::accumulate de <numeric>:



#include <numeric>

std::vector<int> numbers = {1, 2, 3, 4, 5};int sum = std::accumulate(numbers.begin(), numbers.end(), 0, [](int acc, int n) { return acc + n; });// sum = 15


Ejemplo avanzado: Combinamos map, filter y reduce para procesar datos:



std::vector<std::string> names = {"Alice", "Bob", "Charlie", "David"};// Obtenemos la suma de las longitudes de los nombres que comienzan con 'A' o 'C'int result = std::accumulate(names.begin(), names.end(), 0,    [](int acc, const std::string& name) {        if (name[0] == 'A' || name[0] == 'C') {            return acc + name.length();        }        return acc;                

Blogs

Book Recommendations