代码之家  ›  专栏  ›  技术社区  ›  Brian Bi

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

  •  4
  • Brian Bi  · 技术社区  · 7 年前

    看看下面的代码,显然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 回复  |  直到 7 年前
        1
  •  1
  •   Yakk - Adam Nevraumont    7 年前

    [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
    

    但文本有点不清楚:

    如果类模板、变量模板或别名模板的模板参数具有默认模板- 参数,每个后续模板参数应提供默认模板参数,或为 模板参数包。如果主类模板、主变量模板或 alias template是一个模板参数包,它应该是最后一个模板参数。模板参数 一个功能模板的包装后不得有另一个模板参数,除非该模板 参数可以从功能模板的参数类型列表(11.3.5)中推导出来,或者具有默认值 论点(17.9.2)。扣减指南模板(17.10)的模板参数,没有默认值 参数应可从推断指南模板的参数类型列表中推断。

    问题是 模板参数包 这不是一个 模板参数 ; 虽然 T..., U... 对于模板类来说是禁止的,但阻止它使用模板函数的措辞似乎有点错误。

    你也可以说,将类型传递给这些包的不可能性包括:

    该程序格式不正确,无需诊断,如果: [...] 可变模板的每个有效专门化都需要一个空模板参数包,

    但这是一个严重的延伸。