Desafio C++

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

Enunciado

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.

Requisitos

  • A lambda deve ser armazenada em um std::function<void(int)>.
  • A lambda deve capturar total por referência.
  • O programa deve ler inteiros até 0 e somar todos os valores anteriores.
  • O total deve ser impresso no final.

Código inicial

#include <iostream>
#include <functional>

int main() {
    int total = 0;
    // Crie a std::function e leia os valores
    
    return 0;
}

Saída esperada

Total: 15
Ver dica

Use std::function<void(int)> acumula = [&total](int n) { total += n; }; e um loop while para ler até 0.

Mostrar solução
#include <iostream>
#include <functional>

int main() {
    int total = 0;
    // std::function armazena a lambda que captura 'total' por referência
    std::function<void(int)> acumula = [&total](int n) {
        total += n;
    };

    int valor;
    // Lê valores até encontrar 0
    while (std::cin >> valor && valor != 0) {
        acumula(valor);
    }

    std::cout << "Total: " << total << '\n';
    return 0;
}

Passo a passo

  1. Declaramos int total = 0; para acumular a soma.
  2. Criamos std::function<void(int)> acumula e atribuímos uma lambda que captura total por referência ([&total]).
  3. A lambda soma o argumento n a total.
  4. No loop while, lemos um inteiro por vez; se a leitura falhar ou o valor for 0, o loop termina.
  5. Para cada valor lido diferente de 0, chamamos acumula(valor).
  6. Ao final, imprimimos total.

Por que funciona

std::function permite armazenar a lambda como um objeto callable com assinatura fixa. A captura por referência faz com que a lambda modifique a variável total original. O loop lê até 0, somando todos os valores anteriores. A saída mostra o total acumulado.

Erros comuns

  • Capturar por valor ([total]): a lambda modificaria uma cópia e total externo permaneceria 0.
  • Esquecer de incluir <functional>: erro de compilação ao usar std::function.
  • Não verificar a entrada: se o usuário digitar algo não numérico, o loop pode entrar em estado de falha e não terminar corretamente.
  • Usar std::function desnecessariamente: poderia ser auto, mas o enunciado pede std::function.

Outra forma de resolver

Usar auto em vez de std::function:

auto acumula = [&total](int n) { total += n; };

Isso evita o overhead de type erasure, mas não permite armazenar a lambda em um contêiner homogêneo de callables.

Saída esperada

Total: 15