Programação Funcional em C++: de Lambdas a Algoritmos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
Here is the translated HTML content in Portuguese (Português), with all HTML tags preserved and only the text content translated: ```html

Programação Funcional em C++: de Lambdas à Composição



Programação Funcional (PF) é um paradigma no qual os cálculos são construídos com base na aplicação de funções puras, imutabilidade de dados e ausência de efeitos colaterais. Embora C++ tenha sido originalmente uma linguagem multiparadigma, seus padrões modernos (C++11/14/17/20) introduziram ferramentas poderosas para PF: expressões lambda, std::function, algoritmos STL, corrotinas e até suporte a padrões mônadas. Neste artigo, vamos explorar como escrever código funcional em C++ sem perder desempenho.



1. Fundamentos do Estilo Funcional: Lambdas e std::function



Expressões lambda são o coração da PF em C++. Elas permitem criar funções anônimas "em tempo real", capturando o 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 com o 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;}


Pontos-chave das lambdas:

  • Captura — [=] (por valor), [&] (por referência), [this] (para métodos de classe).
  • Tipo — cada lambda tem um tipo único, portanto, para passá-la a uma função, usa-se std::function ou templates.
  • Valor de retorno — é deduzido automaticamente, a menos que especificado de outra forma.


std::function — um wrapper para objetos callable (funções, lambdas, functores). É conveniente para armazenar e passar, mas adiciona overhead (chamada virtual).



#include <functional>

void apply_twice(std::function<int(int)> f, int x) { std::cout << f(f(x)) << std::endl; // Composição}

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


2. Algoritmos STL como Base para Cadeias Funcionais



Os algoritmos STL (std::transform, std::copy_if, std::accumulate, etc.) se encaixam perfeitamente no estilo funcional. Eles não modificam os contêineres diretamente, mas aceitam iteradores e retornam resultados.



Exemplo: filtragem e transformação (map/filter)



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

int main() { std::vector<int> data = {1, 2, 3, 4, 5, 6}; // Abordagem clássica (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; }); // Abordagem moderna com 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;}


Dobra (fold) com std::accumulate



#include <numeric>

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

Blogs

Book Recommendations