所有模板参数包的默认值是否都为“空”?

时间:2018-11-18 02:43:01

标签: c++ templates standards

请看下面的代码,显然GCC和Clang都很高兴接受:[coliru]:

template <class ... P1, class T1, class ... P2, class T2, class ... P3>
constexpr int f(T1, T2) {
    return sizeof...(P1) + sizeof...(P2) + sizeof...(P3);
}
int main() {
    static_assert(f(12, 3.4) == 0);
}

为什么要编译?标准中是否有一条规则规定,当无法推导模板参数包时,假定它为空?

1 个答案:

答案 0 :(得分:1)

[temp.param] 17.1 / 15打算根据示例使您的代码格式错误:

 // U can be neither deduced from the parameter-type-list nor specified
 template<class... T, class... U> void f() { } // error

但是文字有点不清楚:

  

如果类模板,变量模板或别名模板的模板参数具有默认模板,   参数,随后的每个template-parameter必须提供一个默认template-argument或为   模板参数包。如果是主要类别范本,主要变数范本或   别名模板是模板参数包,它应该是最后一个模板参数。模板参数   一组功能模板之后不应再有另一个模板参数,除非该模板   参数可以从功能模板的parameter-type-list(11.3.5)推导出,也可以使用默认值   论点(17.9.2)。演绎指南模板(17.10)的模板参数没有默认值   参数可以从推导指南模板的parameter-type-list中推导。

问题是模板参数包不是模板参数;尽管T..., U...禁止用于模板类,但将其从模板函数中阻止的措辞似乎有点错误。

您还可以争辩说,将类型传递给这些包的可能性不大:

  

该程序格式错误,如果出现以下情况,则无需进行诊断:   [...]   可变参数模板的每个有效专业化都需要一个空的模板参数包,

但这是一个严重的延误。