Кратко:

Пакеты шаблонных параметров позволяют шаблонам принимать произвольное количество типов или значений.

Синтаксис

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

Пример кода

Пример 1: Шаблонная функция с пакетом параметров. Оно же - реализация print в Python

#include <iostream>
 
template<typename... Args>
void print(Args... args) {
    (std::cout << ... << args) << std::endl; // Распаковка параметров пакета
}
 
int main() {
    print(1, 2, 3);       // Output: 123
    print("Hello, ", "world!"); // Output: Hello, world!
    print(1.5, 'A', "text"); // Output: 1.5Atext
 
    return 0;
}

Пример 2: Шаблонный класс с пакетом параметров

#include <iostream>
#include <tuple>
 
template<typename... Types>
class TupleWrapper {
public:
    std::tuple<Types...> data;
 
    TupleWrapper(Types... args) : data(std::make_tuple(args...)) {}
 
    void print() {
        printTuple(data);
    }
 
private:
    template<std::size_t... Is>
    void printTupleImpl(const std::tuple<Types...>& t, std::index_sequence<Is...>) {
        ((std::cout << std::get<Is>(t) << " "), ...) << std::endl;
    }
 
    void printTuple(const std::tuple<Types...>& t) {
        printTupleImpl(t, std::index_sequence_for<Types...>{});
    }
};
 
int main() {
    TupleWrapper<int, double, std::string> tw(1, 2.5, "example");
    tw.print(); // Output: 1 2.5 example 
 
    return 0;
}