Functors em C++: o que são e como simplificam o código? Guia completo

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

O que são functors em C++ e para que servem?

\n\n

Imagine que você está escrevendo código em C++ e precisa passar um comportamento (função) para outra função, por exemplo, para ordenar ou filtrar dados. A solução clássica são os ponteiros para funções. Mas eles têm desvantagens: não armazenam estado, são difíceis de incorporar (inline) e parecem um pouco arcaicos. É aqui que entram os functors em C++ (também conhecidos como objetos-função ou objetos funcionais C++).

\n\n

Um functor é uma classe ou estrutura comum na qual o operador de chamada de função operator() é sobrescrito. Graças a isso, uma instância dessa classe pode ser usada como uma função comum. Parece complicado? Na verdade, é uma das ferramentas mais elegantes do C++. No Stack Overflow, a pergunta "What are C++ functors and their uses?" teve milhares de visualizações — desenvolvedores querem entender este tópico para escrever código mais flexível e eficiente. Neste guia, vamos detalhar tudo: desde a sintaxe básica até exemplos reais de uso com STL.

\n\n

Sintaxe básica: como criar seu primeiro functor

\n\n

Criar um functor se resume a três etapas:

\n
    \n
  • Declarar uma classe ou estrutura.
  • \n
  • Implementar internamente o operator() com a assinatura desejada (parâmetros e tipo de retorno).
  • \n
  • Criar um objeto dessa classe e chamá-lo como uma função.
  • \n
\n\n

Aqui está um exemplo simples de functor C++ que multiplica um número por dois:

\n\n
#include <iostream>\n\nclass Multiplier {\npublic:\n    // Sobrescrevemos o operador ()\n    int operator()(int x) const {\n        return x * 2;\n    }\n};\n\nint main() {\n    Multiplier mult;  // Criamos um objeto-função\n    std::cout << mult(5) << std::endl; // Saída: 10\n    std::cout << mult(10) << std::endl; // Saída: 20\n    return 0;\n}
\n\n

Observe: mult(5) parece uma chamada de função comum, mas na verdade é uma chamada a mult.operator()(5). O compilador faz o açúcar sintático, e o código fica limpo e intuitivo.

\n\n

Principal vantagem: functors podem armazenar estado

\n\n

Ao contrário de funções comuns ou expressões lambda (antes do C++11), os objetos função C++ podem ter seus próprios campos-membro. Isso abre enormes possibilidades. Por exemplo, você pode criar um functor que não apenas executa uma ação, mas também lembra quantas vezes foi chamado:

\n\n
#include <iostream>\n\nclass Counter {\nprivate:\n    int count = 0;\npublic:\n    int operator()() {\n        return ++count;\n    }\n    int getCount() const { return count; }\n};\n\nint main() {\n    Counter counter;\n    std::cout << counter() << std::endl; // 1\n    std::cout << counter() << std::endl; // 2\n    std::cout << counter() << std::endl; // 3\n    // O estado é preservado entre as chamadas!\n    return 0;\n}
\n\n

Este exemplo de functor C++ com estado não pode ser implementado com uma função simples sem usar variáveis globais (o que é ruim). Os functors resolvem esse problema de forma elegante e segura.

\n\n

Functors e algoritmos STL: a combinação perfeita

\n\n

A aplicação mais poderosa dos functors é o trabalho com algoritmos da Standard Template Library (STL). Algoritmos como std::sort, std::find_if, std::for_each esperam receber um objeto chamável (callable). Você pode passar um functor para eles, e ele executará a lógica necessária.

\n\n

Exemplo: ordenação com functor

\n\n

Suponha que você tenha um vetor de números e queira ordená-los em ordem decrescente. Você pode escrever seu próprio functor de comparação:

\n\n
#include <iostream>\n#include <vector>\n#include <algorithm>\n\nclass Descending {\npublic:\n    bool operator()(int a, int b) const {\n        return a > b; // Ret                

Blogs

Book Recommendations