… в параметрах шаблонной функции

183
09 мая 2019, 14:50

В чём разница между следующими объявлениями? Как правильно вызывать оба варианта?

template<typename T>
void foo(T...);
template<typename... T>
void foo(T...);
Answer 1

Первый вариант эквивалентен

template<typename T>
void foo(T, ...);

то есть первый параметр функции имеет тип T (шаблонный параметр), а остальные параметры - это классические унаследованные из языка C переменные параметры, доступ к которым осуществляется через va_list и макросы из <stdarg.h>. С++, однако, разрешает не ставить запятую перед ..., что и делает ваш первый вариант корректным.

Второй вариант

template<typename... T>
void foo(T...);

это появившийся в С++11 шаблонный параметр pack.

Вызывать оба варианта можно одинаково - указывайте аргументы и все. Разница только в том, что первый вариант требует хотя бы одного аргумента, а второй вариант может быть вызван вообще без аргументов. Также в С++ значения не всех типов разрешается передавать как аргументы для ... параметров в первом варианте.

P.S. Оба варианта синтаксиса можно скомбинировать в одном объявлении, получив необычно выглядящее

template<typename... T>
void foo(T......);

Если обе функции видны одновременно, то основные правила overload resolution, которые работают в таких случаях, это

  1. Преобразование аргумента к параметру ... (ellipsis conversion sequence) обладает наименьшим рангом, т.е. является наименее предпочтительным, по сравнению с другими преобразованиями.

  2. Шаблонная функция с "конкретным" шаблонным параметром является более специализированной и более предпочтительной, чем функция с параметром, полученным из parameter pack.

По этим правилам, например, вызов foo(1) вызовет первый вариант (работает правило 2), а вызов foo(1, 2) вызовет второй вариант(работает правило 1).

READ ALSO
Ошибка при определении функции xor

Ошибка при определении функции xor

ругается на месте bool xor

194
Неоднозначный вызов шаблонных функций

Неоднозначный вызов шаблонных функций

Как правильно вызывать каждую из функций? Почему в первом случае вызывается первая функция, а во втором - вторая?

165