Ответ 1
Изначально я буквально ответил на этот вопрос, но я хотел немного расширить его, чтобы дать более подробное объяснение того, как пакеты расширяются. Так или иначе я думаю о вещах.
Любая упаковка, сразу же за которой следуют эллипсы, просто расширяется. Итак, A<Ts...>
эквивалентно A<T1, T2, ..., TN>
, а hun(vs...)
аналогично эквивалентно hun(v1, v2, ..., vn)
. Там, где это осложняется, вместо того, чтобы пакет, за которым следуют эллипсы, вы получаете что-то вроде ((expr)...)
. Это расширится до (expr1, expr2, ..., exprN)
, где expri
относится к исходному выражению с любым пакетом, замененным его версией i
th. Поэтому, если у вас есть hun((vs+1)...)
, это становится hun(v1+1, v2+1, ..., vn+1)
. Там, где становится все веселее, expr
может содержать более одного пакета (если все они имеют одинаковый размер!). Вот как мы реализуем стандартную идеальную модель пересылки;
foo(std::forward<Args>(args)...)
Здесь expr
содержит две упаковки (Args
и Args
- оба пакета), а расширение "итерации" по обоим:
foo(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), ..., std::forward<ArgN>(argN));
Это рассуждение должно позволить вам быстро пройтись по вашим делам, скажем, что происходит, когда вы вызываете foo(1, 2, '3')
.
Первая, gun(A<Ts...>::hun(vs)...);
расширяет Ts
"на месте", а затем появляется выражение для расширения для последних эллипсов, поэтому это вызывает:
gun(A<int, int, char>::hun(1),
A<int, int, char>::hun(2),
A<int, int, char>::hun('3'));
Второй, gun(A<Ts...>::hun(vs...));
расширяет обе пакеты на месте:
gun(A<int, int, char>::hun(1, 2, '3'));
Третий, gun(A<Ts>::hun(vs)...)
, одновременно расширяет обе упаковки:
gun(A<int>::hun(1),
A<int>::hun(2),
A<char>::hun('3'));
[обновление] Для полноты gun(A<Ts>::hun(vs...)...)
вызовет:
gun(A<int>::hun(1, 2, '3'),
A<int>::hun(1, 2, '3'),
A<char>::hun(1, 2, '3'));
Наконец, есть один последний случай, чтобы рассмотреть, где мы выходим за борт на эллипсах:
gun(A<Ts...>::hun(vs...)...);
Это не будет компилироваться. Мы расширяем как Ts
, так и vs
"на месте", но тогда у нас нет пакетов для расширения для конечных эллипсов.