为什么模板只有有效的空可变参数包形成?

Jar*_*d42 9 c++ templates language-lawyer variadic-templates

什么是理由

temp.res#8.3

(8)可以在任何实例化之前检查模板的有效性.[注意:知道哪些名称是类型名称允许以这种方式检查每个模板的语法.- 结束注释]程序格式错误,无需诊断,如果:
[..]
(8.3)可变参数模板的每个有效特化都需要一个空的模板参数包,或者

该规则不允许使用如下强制模板扣除的技巧:

template <typename ...Ts,
          typename A,
          typename B,
          std::enable_if_t<sizeof...(Ts) == 0, int> = 0> // Ill-formed NDR :-(
Pair<std::decay_t<A>, std::decay_t<B>> MakePair(A&&a, B&& b)
{
    return {a, b};
}
Run Code Online (Sandbox Code Playgroud)

注意:我知道C++ 17演绎规则make_*已经过时了.

T.C*_*.C. 6

通常,由于您始终无法生成有效的实例,因此实现可以及早诊断出模板中的明显错误。但是pack扩展有点独特,因为整个构造在实例化时就可以消失。因此,需要使用该规则来禁止在包装扩展的事物中出现各种明显的bossity,并允许对其进行早期诊断:

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};
}
Run Code Online (Sandbox Code Playgroud)

这也对编译器实现者有所帮助,因为它们的内部模板表示不需要支持这种废话。