Объект функции (function object) или функтор (functor) представляет объект, который может вызываться как функция. Для этого применяется оператор (). Рассмотрим простейший пример:
#include <iostream>
#include <string>
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 после инкремента.