Объект функции (function object) или функтор (functor) представляет объект, который может вызываться как функция. Для этого применяется оператор (). Рассмотрим простейший пример:
#include <iostream> class Print { public: void operator()(const std::string& message) const { std::cout << message << std::endl; } }; int main() { Print print; // определяем объект функции print("Hello"); // выполняем как функцию print("World"); }
Здесь определен класс Print. В нем определена функция оператора (), которая принимает один параметр - некоторую строку и ничего не возвращает. Внутри функции оператора выводим переданную строку на консоль.
Сколько параметров будет принимать функция оператора, какие типы эти параметры будут представлять и какой результат будет возвращать функция - все это мы сами определяем исходя из своих задач. Но стоит отметить, что такой оператор может быть определен только как функция-член класса.
Затем мы можем определить объект этого класса и вызвать его как функцию, передав один аргумент:
print("Hello");
Другой пример:
#include <iostream> class Sum { public: int operator()(int x, int y) const { return x + y; } }; int main() { Sum sum; // определяем объект функции int result {sum(2, 3)}; // вызываем объект функции std::cout << result << std::endl; // 5 std::cout << sum(5, 3) << std::endl; // 8 std::cout << sum(12, 13) << std::endl; // 25 }
Здесь определяется класс Sum, в котором функция оператора принимает два числа и возвращает их сумму. Поскольку функция оператора возвращает значение int, мы можем присвоить этот результат переменной int и вообще использовать как int.
Подобные объекты-функции также могут хранить некоторое состояние:
#include <iostream> class Id { public: unsigned operator()() { return ++id; } private: unsigned id{}; }; int main() { Id id; // определяем объект функции std::cout << id() << std::endl; // 1 std::cout << id() << std::endl; // 2 std::cout << id() << std::endl; // 3 }
Здесь объект-функция Id возвращает значение приватной переменной id после инкремента.