Da trilha de C++ Este conceito ainda não saiu como card do dia. ir para o card de hoje

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 auto nos parâmetros e aceitam tipos diferentes.
  • std::function pode armazenar lambdas e outras callables, mas tem overhead em relação a auto.
  • Cuidado ao capturar por referência variáveis locais que podem sair de escopo antes da lambda ser chamada.
lambdas.cpp
#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;
}

Exercícios

  1. 1
    Fácil

    Lambda que multiplica por um fator capturado

    Crie uma lambda que receba um inteiro e retorne esse inteiro multiplicado por um fator. O fator deve ser capturado por valor de uma variável externa chamada fator.

    Resolver
  2. 2
    Médio

    Lambda genérica que imprime qualquer tipo

    Crie uma lambda genérica que receba um parâmetro auto e imprima esse valor seguido de uma quebra de linha. Chame a lambda com um int, um double e uma std::string.

    Resolver
  3. 3
    Desafio

    Acumulador com std::function e captura por referência

    Implemente um acumulador que soma valores usando uma lambda armazenada em std::function. A lambda deve capturar uma variável total por referência e somar o argumento a ela. O programa deve ler uma sequência de inteiros da entrada padrão até encontrar 0, somar cada um usando a lambda e imprimir o total ao final.

    Resolver

Continue estudando