GCC与Clang处理C++17可变参类模板的可变参成员模板行为差异
结论
Clang 12.0.1 的行为符合 C++ 标准规范,GCC 11.1 的编译报错属于编译器自身的实现缺陷。
规则说明与错误原因
- 外层类模板
A的模板参数是类型参数包Ts,实例化A<int, int, int, int>后,Ts会被展开为包含 4 个int的类型序列。 - 内层静态成员模板
f的模板参数是非类型参数包,类型序列直接复用外层的Ts,因此此时f要求传入恰好 4 个int类型的非类型模板实参。 - 调用处的
A<int, int, int, int>::f<0, 1, 2, 3>()传入的 4 个 int 字面量完全匹配参数要求,代码本身符合 C++17 的语法规则。
GCC 11.x 及更早版本在处理「复用外层类型参数包作为内层非类型参数包的类型序列」的场景时存在解析缺陷,错误地将内层的 Ts ...Args 识别为单类型的参数包,即认为所有参数包元素的类型都是同一个 Ts,而非将外层的 Ts 包展开为多个类型对应参数包的每个元素,才会抛出「模板参数数量错误,应为1个」的报错。该问题在 GCC 12 及更高版本中已经被修复,新版 GCC 可以正常编译运行这段代码。
内容的提问来源于stack exchange,提问作者vbstb
相关产品推荐
相关产品推荐

