0Pricing
C++ Academy · Урок

std::function: вызываемые объекты со стиранием типа

Скрывайте типы за std::function и изучайте оптимизацию малого буфера.

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

Проблема: один тип для множества вызываемых объектов

У каждого лямбда-выражения уникальный тип. Каждый указатель на функцию также имеет отдельный тип. Нам нужен один тип, способный хранить любой из них, — std::function.

Параметр шаблона

std::function<Signature> принимает тип возвращаемого значения и типы параметров. Он принимает любой вызываемый объект с такой сигнатурой.

#include <functional>
std::function<int(int, int)> op;
op = [](int a, int b) { return a + b; };
std::cout << op(3, 4);   // 7

Хранение разных вызываемых объектов

Одна и та же переменная типа std::function может хранить лямбда-выражение, указатель на функцию или функтор, если сигнатуры совпадают.

std::function<int(int)> f;
f = [](int x) { return x * 2; };       // lambda
f = ::abs;                              // function pointer
f = std::negate<int>{};                  // functor

Стирание типа

Внутри std::function использует стирание типа: он хранит любой вызываемый объект и скрывает его настоящий тип за единым интерфейсом. Часто это реализуется с небольшим выделением памяти в куче.

Производительность

Вызов через std::function включает косвенный вызов, похожий на вызов виртуальной функции. Он медленнее прямого вызова лямбда-выражения. Избегайте его на критических участках кода.

Когда следует использовать std::function

Используйте его, если:

  • Храните обратные вызовы в контейнере или в члене класса
  • Возвращаете вызываемый объект из функции
  • Создаёте систему плагинов или событий

Пустой std::function

Объект std::function, созданный конструктором по умолчанию, пуст. Вызов такого объекта выбрасывает исключение std::bad_function_call.

std::function<void()> f;
if (f) f(); else std::cout << "no callback set";

Указатели на функции-члены

Свяжите функцию-член с помощью std::bind или оберните её в лямбда-выражение.

struct Obj { void greet(int) {} };
Obj o;
std::function<void(int)> cb = [&](int n) { o.greet(n); };

Сравнение с указателями на функции

Указатели на функции не могут хранить состояние. std::function может, но ценой косвенных вызовов.

Сравнение с шаблонами

Шаблоны с параметрами-вызваемыми объектами специализируются во время компиляции и работают быстрее всего. std::function разрешает вызов во время выполнения: он медленнее, но гибче.

template <typename F>
void run(F f) { f(); }            // compile-time, no overhead

void run(std::function<void()> f) { f(); }   // runtime, type erasure

std::function в C++23: std::function_ref

В C++23 появился std::function_ref — невладеющее представление вызываемого объекта. Оно избегает выделения памяти в куче, когда срок действия ограничен.

Альтернативы

Существуют облегчённые альтернативы: std::move_only_function (C++23), tl::function_ref, folly::Function. Выбирайте вариант в зависимости от требований.

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

Каков главный недостаток std::function?

Итоги

std::function<Signature> хранит любой вызываемый объект с подходящей сигнатурой. Он полезен для обратных вызовов, плагинов и полиморфизма времени выполнения для вызываемых объектов, но требует косвенных вызовов.

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

Урок «std::function: вызываемые объекты со стиранием типа» бесплатный?

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

Чему я научусь в уроке «std::function: вызываемые объекты со стиранием типа»?

Скрывайте типы за std::function и изучайте оптимизацию малого буфера. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

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

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

Сколько времени занимает урок «std::function: вызываемые объекты со стиранием типа»?

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

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

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

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

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