gcc 和 clang 对于以下代码是否应该编译存在分歧:
template <typename... Args>
struct tuple {};
template <typename>
struct Test;
template <
typename... Types,
template <Types> typename... Outer, // XXX
Types... Inner
>
struct Test<tuple<Outer<Inner>...>> {};
template <long T> struct O1 {};
template <unsigned T> struct O2 {};
Test<tuple<O1<1>, O2<2>>> test;
clang 接受代码,推导出Types = {long, unsigned}, Outer = {O1, O2}, Inner={1L, 2U}
。从结构上看,这似乎是正确的。
gcc 因推导失败而拒绝该代码。有趣的是,它does接受如果O2
改为采取long
非类型模板参数,这对我来说似乎不一致。它表明类型可以扩展,如果Types = {long, long}
但不是如果Types = {long, unsigned}
.
但是,从标准中我不清楚哪个编译器是正确的。核心问题是:在表示的线上XXX
,将参数包作为模板模板参数的非类型模板参数的类型是否有效?它应该像 clang 声称的那样扩展吗?