Вариативные шаблоны и пакеты параметров
Используйте пакеты параметров и свёрточные выражения для написания вариативных шаблонов.
«Вариативные шаблоны и пакеты параметров» — бесплатный урок 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 — локальная установка не требуется.
Все уроки этого курса
- Шаблоны функций и классов: повторение
- Специализация шаблонов: частичная и полная
- Вариативные шаблоны и пакеты параметров
- Функции constexpr и if constexpr