16.4. Шаблоны с переменным количеством аргументов
Для указания, что шаблону или функции представлен пакет параметров, используется многоточие. В списке параметров шаблона синтаксис class... или typename... означает, что следующий параметр представляет список любого количества типов; имя типа, сопровождаемое многоточием, представляет список из любого количества параметров значения заданного типа. Параметр в списке параметров функции, типом которого является пакет параметров шаблона, представляет собой пакет параметров функции. Например:
// Args - это пакет параметров шаблона; rest - пакет параметров функции
// Args представляет любое количество параметров типа шаблона
// rest представляет любое количество параметров функции
template <typename Т, typename... Args>
void foo(const T &t, const Args& ... rest);
Этот код объявляет, что fоо() — это функция с переменным количеством аргументов, у которой один параметр типа по имени T и пакет параметров шаблона по имени Args. Этот пакет представляет любое количество дополнительных параметров типа. В списке параметров функции foo() один параметр типа const& для любого типа переданного параметром Т и пакет параметров функции rest. Этот пакет представляет любое количество параметров функции.
Как обычно, компилятор выводит типы параметра шаблона из аргументов функции. Для шаблона с переменным количеством аргументов компилятор также выводит количество параметров в пакете. Рассмотрим, например, следующие вызовы:
int i = 0; double d = 3.14; string s = "how now brown cow";
foo(i, s, 42, d); // три параметра в пакете
foo(s, 42, "hi"); // два параметра в пакете
foo(d, s); // один параметр в пакете
foo("hi"); // пустой пакет
Компилятор создаст четыре разных экземпляра функции fоо():
void foo(const int&, const string&, const int&, const double&);
void foo(const string&, const int&, const char[3]&);
void foo(const double&, const string&);
void foo(const char[3]&);
В каждом случае тип T выводится из типа первого аргумента. Остальные аргументы (если они есть) представляют количество и типы дополнительных аргументов функции.
Оператор sizeof...
template<typename ... Args> void g(Args ... args) {
cout << sizeof...(Args) << endl; // количество параметров типа
cout << sizeof...(args) << endl; // количество параметров функции
}
Упражнения раздела 16.4
Упражнение 16.51. Определите, что возвратят операторы sizeof...(Args) и sizeof...(rest) для каждого вызова функции foo() в этом разделе.
Упражнение 16.52. Напишите программу, проверяющую ответы на предыдущий вопрос.