Как правило, реализации могут диагностировать очевидные ошибки в шаблонах на ранних этапах, так как вы все равно не можете сгенерировать действительные экземпляры.Но расширение пакета немного уникально, потому что вся конструкция может просто исчезнуть при создании экземпляра.Следовательно, это правило необходимо, чтобы запретить различные виды очевидной завуалированности в вещах, расширяемых пакетами, и разрешить их раннюю диагностику:
template<class...Ts>
union U : Ts... {}; // unions can't have base classes
template<class...Ts>
class C : Ts..., Ts... {}; // classes can't have duplicate direct base classes
template<class...Ts>
void f() {
// sizeof(void) is invalid, but it can vanish
int x[] = {(sizeof(void) + sizeof(Ts))..., 0};
}
Это также несколько помогает разработчикам компиляторов, поскольку их внутреннее представление для шаблонов не должно поддерживать такиенонсенс.