0Pricing
C++ Academy · Урок

Функциональные объекты и функторы

Пишите классы с operator(), чтобы создавать вызываемые объекты с состоянием.

«Функциональные объекты и функторы» — бесплатный урок C++ Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Что такое функтор

Функтор (функциональный объект) — это класс, перегружающий operator(). Его экземпляры можно вызывать как функции.

struct Square {
    int operator()(int x) const { return x * x; }
};

Square sq;
std::cout << sq(5);   // 25

Почему не обычная функция

Функторы хранят состояние. Обычная функция — нет. Состояние позволяет задавать конфигурацию, вести подсчёт и использовать обратные вызовы с состоянием.

struct Counter {
    int count = 0;
    int operator()(int x) { ++count; return x; }
};

Counter c;
c(10); c(20); c(30);
std::cout << c.count;   // 3

Настраиваемое поведение

Храните конфигурацию в членах функтора. Один и тот же тип функтора подходит для множества наборов параметров.

struct GreaterThan {
    int threshold;
    bool operator()(int x) const { return x > threshold; }
};

GreaterThan over10{10};
over10(15);    // true
over10(5);     // false

Использование функторов с алгоритмами STL

Алгоритмы STL принимают любой вызываемый объект — функторы, лямбда-выражения и указатели на функции.

std::vector<int> v = {1, 11, 5, 99, 8};
auto it = std::find_if(v.begin(), v.end(), GreaterThan{10});
std::cout << *it;   // 11

Предопределённые функторы в <functional>

Стандартная библиотека предоставляет готовые функторы: std::plus, std::less, std::equal_to, std::negate и другие.

#include <functional>
std::vector<int> v = {3, 1, 4, 1, 5};
std::sort(v.begin(), v.end(), std::greater<int>{});
// sorted descending

Функтор и указатель на функцию

Функторы обычно лучше встраиваются, поскольку их operator() представляет собой прямой вызов. Указатели на функции могут быть более гибкими, но обеспечивают косвенный вызов.

Функторы как параметры шаблона

Многие контейнеры и алгоритмы STL принимают функтор в качестве параметра шаблона — например, компараторы множеств, хеш-функции и распределители памяти.

std::set<int, std::greater<int>> s = {1, 2, 3};
// s iterates in descending order: 3, 2, 1

Лямбда-выражения — это функторы

Компилятор создаёт уникальный класс с operator() для каждого лямбда-выражения. Лямбда-выражения являются синтаксическим упрощением для функторов.

Когда следует писать функтор

Используйте написанный вручную функтор, если:

  • Одна и та же логика используется во многих местах (дайте ей имя)
  • Он является частью вашего публичного API
  • Для него требуется определённое поведение при конструировании копированием или перемещением

Когда вместо него следует использовать лямбда-выражение

Для разового использования лямбда-выражение короче и понятнее. Для повторно используемого поведения именованный функтор повышает читаемость.

Компонуемость

Объединяйте функторы с помощью std::bind или, что современнее, компонуя лямбда-выражения. Функциональные библиотеки, такие как Boost, также предоставляют комбинаторы.

Быстрая проверка

Какова главная возможность функтора по сравнению с обычной функцией?

Итоги

Функтор — это класс с operator(). Он хранит состояние, интегрируется с алгоритмами STL и служит основой для лямбда-выражений. Используйте именованные функторы для повторно используемого поведения, а лямбда-выражения — для одноразовой логики.

Часто задаваемые вопросы

Урок «Функциональные объекты и функторы» бесплатный?

Да — полный текст урока «Функциональные объекты и функторы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Функциональные объекты и функторы»?

Пишите классы с operator(), чтобы создавать вызываемые объекты с состоянием. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Функциональные объекты и функторы»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Функциональные объекты и функторы
  2. Захват в лямбда-выражениях: по значению, по ссылке, mutable
  3. Обобщённые лямбда-выражения и замыкания в C++14
  4. std::function: вызываемые объекты со стиранием типа
← Назад к C++ Academy