C++ Funções Intermediário
Lambdas
As lambdas são funções anônimas introduzidas no C++11 que permitem definir funções inline, muitas vezes para uso imediato em algoritmos ou callbacks. A sintaxe básica é [captura](parâmetros) -> tipo_retorno { corpo }, onde o tipo de retorno pode ser omitido se o compilador puder deduzi-lo.
A captura define quais variáveis do escopo externo ficam visíveis dentro da lambda. Pode ser por valor ([x]), por referência ([&x]), ou ambas ([x, &y]). Também é possível capturar tudo por valor ([=]) ou por referência ([&]), mas evite capturar tudo por referência se a lambda for armazenada e usada depois que as variáveis saírem de escopo.
Lambdas genéricas (C++14) usam auto nos parâmetros, permitindo que a mesma lambda opere com tipos diferentes. Já std::function é um wrapper que pode armazenar qualquer callable (funções, lambdas, functors) com uma assinatura específica, útil para callbacks e polimorfismo em tempo de execução, mas com custo de performance devido ao type erasure.
Neste card, você verá como declarar lambdas, capturar variáveis corretamente, usar lambdas genéricas e armazenar lambdas em std::function.
Pontos-chave
- A sintaxe básica é
[captura](parâmetros) { corpo }; o tipo de retorno é deduzido automaticamente. - Captura por valor (
[x]) copia a variável; por referência ([&x]) permite modificá-la fora da lambda. - Lambdas genéricas usam
autonos parâmetros e aceitam tipos diferentes. std::functionpode armazenar lambdas e outras callables, mas tem overhead em relação aauto.- Cuidado ao capturar por referência variáveis locais que podem sair de escopo antes da lambda ser chamada.
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
int main() {
// Lambda simples que soma dois inteiros
auto soma = [](int a, int b) { return a + b; };
std::cout << "Soma: " << soma(3, 4) << '\n';
// Captura por valor
int x = 10;
auto porValor = [x](int y) { return x + y; };
x = 100; // não afeta a lambda
std::cout << "Por valor: " << porValor(5) << '\n';
// Captura por referência
int contador = 0;
auto incrementa = [&contador]() { ++contador; };
incrementa();
incrementa();
std::cout << "Contador: " << contador << '\n';
// Lambda genérica (C++14)
auto imprime = [](const auto& valor) { std::cout << valor << '\n'; };
imprime(42);
imprime("texto");
// Armazenando em std::function
std::function<int(int)> dobro = [](int n) { return n * 2; };
std::cout << "Dobro: " << dobro(7) << '\n';
// Usando lambda com algoritmo
std::vector<int> nums = {1, 2, 3, 4, 5};
int somaTotal = 0;
std::for_each(nums.begin(), nums.end(), [&somaTotal](int n) { somaTotal += n; });
std::cout << "Soma total: " << somaTotal << '\n';
return 0;
}