Подтвердить что ты не робот

Шаблоны Variadic, пакет параметров и обсуждаемая двусмысленность в списке параметров

В этом вопросе я буду ссылаться на мой предыдущий вопрос.

В этом вопросе я обнаружил, что следующее недопустимо:

template<typename T, typename... A, typename S>
class C { };

Это происходит потому, что:

[Это недопустимый код] для шаблонов классов, потому что их аргументы всегда должны быть указаны, что всегда будет приводить к неопределенности, если пакет параметров не находится в конце и не перекрывает любые оставшиеся параметры шаблона.

Это, конечно, имеет смысл, и я понял.

Затем в качестве альтернативного подхода было предложено следующее, которое включает специализацию:

template<typename F, typename S>
class C;

template<typename T, typename... A, typename S>
class C<T(A...), S> { };

На самом деле, похоже, он работает, поэтому благодаря тому, который его предложил.

В любом случае, я не понимаю, почему это действительный код, в то время как предыдущий не был.
Должно ли оно страдать от той же двусмысленности предыдущего решения? Почему и как компилятор разрешает эту двусмысленность в этом случае?
Согласно предыдущему вопросу (см. Ссылку в начале этого вопроса), мне кажется, что все же вариационная часть должна заканчивать любые параметры до конца, поэтому этот код также не должен быть действительным.
Я ошибаюсь, конечно, но что неправильно в моих рассуждениях?

4b9b3361

Ответ 1

В шаблоне класса список предполагаемых аргументов шаблона C<a,b,c,d,e,f> должен соответствовать

template<typename T, typename... A, typename S>

в котором... A просто плавает в списке параметров.

Но в специализации то, что должно быть сопоставлено, - это не список шаблонов, а шаблон:

C<T(A...), S>

что легко, потому что A... разделяется.

Таким образом, в специализации шаблона список параметров - это просто инвентаризация символов, некоторых скалярных и некоторых пакетов параметров, которые будут отображаться в шаблоне.