我可以扩展一个参数包并用它定义一个参数列表吗?

Can I expand a parameters pack and define an arguments list with it?

[temp.variadic](工作草案)开始,在我看来,在定义另一个模板 class 或函数的参数列表时,可以扩展参数包。

考虑以下 class:

template<typename... T>
struct S {
    template<T... I>
    void m() {}
};

int main() {
    S<int, char> s;
    // ...
}

目的是 捕获 用于特化模板的类型 class S 并使用它们定义非类型参数的参数列表对于成员方法 m (当然,T 仅限于几种类型,但这不是问题的论点)。

这是法典吗?我可以按照我使用的方式使用参数包还是我误解了标准(很确定确实如此)?


为了向问题添加更多细节,以下是一些主要编译器的实验结果:

至少,编译器似乎和我一样困惑。

模板S的定义和S<int, char>的实例化是有效的。

参见 [temp.param]/15:"A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded parameter packs is a pack expansion."

这意味着 template<T ...I> 可以表示两种不同的事情之一:如果 T 是非包类型,那么它声明一个普通参数包,接受任意数量的 Ts。但是,如果 T 包含未扩展的参数包,则在实例化外部模板时,参数声明将扩展为参数序列。

您对 m 的第一次调用有效,但对 m 的第二次和第三次调用格式不正确

S<int, char> 的实例化如下所示:

template<>
struct S<int, char> {
  template<int I[=10=], char I>
  void m() {}
};

(其中 I[=20=]I 是包的第一片和第二片 I)。

因此(因为 I[=20=]I 都不能从对 m 的调用中推导出来),s.m<0,'c'>() 是有效的,但是 s.m<0>()s.m<>() 格式错误。