O que são functors em C++ e para que servem?
\n\nImagine 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\nUm 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.
Sintaxe básica: como criar seu primeiro functor
\n\nCriar 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
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\nObserve: 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.
Principal vantagem: functors podem armazenar estado
\n\nAo 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\nEste 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\nFunctors e algoritmos STL: a combinação perfeita
\n\nA 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.
Exemplo: ordenação com functor
\n\nSuponha 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