0Pricing
C++ Academy · Урок

Вариативные шаблоны и пакеты параметров

Используйте пакеты параметров и свёрточные выражения для написания вариативных шаблонов.

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

Переменное число аргументов шаблона

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

Синтаксис пакета параметров

Используйте typename... Ts для объявления пакета параметров типов, а Ts... — для его раскрытия.

template <typename... Args>
void print_all(Args... args) {
    // ...
}

Раскрытие пакета

Многоточие ... после выражения раскрывает пакет в список, разделённый запятыми.

template <typename... Args>
void pass_through(Args... args) {
    other_func(args...);    // pass each arg
}

Рекурсивные вариадические шаблоны (старый стиль)

До C++17 вариадические функции обычно писали рекурсивно: обрабатывали один аргумент, а затем вызывали себя с оставшимися.

// base case
void log() {}

// recursive case
template <typename T, typename... Rest>
void log(T first, Rest... rest) {
    std::cout << first;
    log(rest...);
}

Свёрточные выражения (C++17)

В C++17 появились свёрточные выражения, которые намного понятнее рекурсии. Они применяют оператор ко всему пакету.

template <typename... Args>
auto sum(Args... args) {
    return (args + ...);    // fold +
}

std::cout << sum(1, 2, 3, 4);   // 10

Операторы свёртки

Четыре формы свёртки:

  • (... op pack) — левая свёртка с унарным раскрытием
  • (pack op ...) — правая свёртка
  • (init op ... op pack) — левая свёртка с начальным значением
  • (pack op ... op init) — правая свёртка с начальным значением

Вывод всех аргументов

Распространённый идиоматический приём с использованием свёртки по запятой.

template <typename... Args>
void print_all(Args... args) {
    ((std::cout << args << " "), ...);   // comma fold
}

print_all(1, "hi", 3.14);   // 1 hi 3.14

Подсчёт аргументов

sizeof...(pack) возвращает число элементов в пакете во время компиляции.

template <typename... Args>
void info(Args... args) {
    std::cout << "count = " << sizeof...(args);
}

Вариадические шаблоны классов

Шаблоны классов также могут иметь пакеты параметров. Пример: std::tuple<Ts...>.

template <typename... Ts>
class Tuple {
    // implementation uses recursion or storage tricks
};

Идеальная передача с пакетами

Объединяйте вариадические шаблоны с std::forward, чтобы идеально передавать произвольные аргументы конструктору.

template <typename T, typename... Args>
std::unique_ptr<T> my_make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

Работа с пакетами типов

С помощью специализации шаблонов или свёрточных выражений можно реализовать операции над списками во время компиляции: получение первого и последнего элемента, а также разбиение на начало и хвост.

Проблемы

Распространённые проблемы:

  • Забытое раскрытие пакета (args вместо args...)
  • Порядок вычисления в свёрточных выражениях (для неассоциативных операций важно направление — слева направо или справа налево)
  • Увеличение времени компиляции при глубокой рекурсии

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

Какая возможность C++17 упрощает суммирование всех элементов пакета параметров?

Итоги

Вариадические шаблоны обрабатывают переменное число аргументов шаблона с помощью пакетов параметров. Свёрточные выражения C++17 заменяют рекурсивный вариадический код компактными выражениями. В сочетании с идеальной передачей они лежат в основе функций-фабрик и обобщённой диспетчеризации.

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

Урок «Вариативные шаблоны и пакеты параметров» бесплатный?

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

Чему я научусь в уроке «Вариативные шаблоны и пакеты параметров»?

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

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

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

Сколько времени занимает урок «Вариативные шаблоны и пакеты параметров»?

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

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

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

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

  1. Шаблоны функций и классов: повторение
  2. Специализация шаблонов: частичная и полная
  3. Вариативные шаблоны и пакеты параметров
  4. Функции constexpr и if constexpr
← Назад к C++ Academy