多参数包推导不一致:g++编译失败clang++通过,谁符合C++标准?
代码合规性分析:GCC编译失败属于实现bug
这段代码完全符合C++标准,GCC的编译错误是编译器实现层面的问题,而非代码违反标准规则。
核心规则依据
根据C++模板参数推导的规则,当函数模板的参数包同时通过两类方式推导时:
- 通过模板参数的显式类型(如
SVariadicTypeset<As...>、SVariadicTypeset<Bs...>)推导参数包的类型; - 通过函数的实参(如
As... a_s、Bs... b_s)推导参数包的类型;
只要两种推导结果完全一致,模板参数推导就应当成功。
具体案例分析
以编译失败的moo(SVariadicTypeset<int>{}, SVariadicTypeset<>{}, 1);为例:
- 从模板参数推导:
As为int,Bs为空参数包; - 从函数实参推导:
1匹配As...(即int),剩余无实参匹配Bs...,因此Bs为空参数包;
两种推导结果完全一致,不存在所谓的“推导不一致”,GCC的错误提示不成立。
而GCC能正确编译moo(SVariadicTypeset<>{}, SVariadicTypeset<int>{}, 2);,说明它对参数包的处理存在不对称bug:当第二个参数包非空、第一个为空时推导正常,反过来却错误判定推导不一致。
代码与错误信息
测试代码
template <typename ... Ts> struct SVariadicTypeset {}; template <typename ... As, typename ... Bs> void moo(SVariadicTypeset<As ...>, SVariadicTypeset<Bs ...>, As ... a_s, Bs ... b_s); void baa() { moo(SVariadicTypeset< >{}, SVariadicTypeset< >{}); // ok moo(SVariadicTypeset<int>{}, SVariadicTypeset< >{}, 1); // fails on g++ moo(SVariadicTypeset< >{}, SVariadicTypeset<int>{}, 2); // ok moo(SVariadicTypeset<int>{}, SVariadicTypeset<int>{}, 1, 2); // fails on g++ }
GCC错误信息
:6:6: note: template argument deduction/substitution failed: :11:20: note: inconsistent parameter pack deduction with '' and ''
Clang(trunk版本,C++26)能正常编译这段代码,进一步验证了代码的合规性。
内容的提问来源于stack exchange,提问作者xaxazak
相关产品推荐
相关产品推荐

