扩展非类型形参包来定义带有非类型形参的内部类模板是否合法?



我能够生成的重现问题的最小代码:

template <int>
struct Tag { };
Tag<0> w;
template <int... Is>
struct Outer {
   template <Tag<Is> &...>
   struct Inner {
   };
};
int main() {
   Outer<0>::Inner<w> f;
}

g++(版本6.1.1 20160511)在编译代码时遇到以下错误:

pp.cc: In function ‘int main()’:
pp.cc:14:21: internal compiler error: unexpected expression ‘Is’ of kind template_parm_index
    Outer<0>::Inner<w> f;

并产生冗长而无聊的堆栈跟踪。版本3.6.0中的clang++在编译代码时似乎没有任何问题。带有类型模板参数的相同代码在两个编译器中都可以很好地编译:

template <class>
struct Tag { };
Tag<int> w;
template <class... Ts>
struct Outer {
   template <Tag<Ts> &...>
   struct Inner {
   };
};
int main() {
   Outer<int>::Inner<w> f;
}

所以这是一个g++的bug还是我错过了一些重要的关于非类型可变模板参数扩展不适用于类模板参数扩展?

(没有答案,但可能有人感兴趣)

对于GCC可能相对简单的解决方法:

template <int>
struct Tag { };
Tag<0> w;
template <class... Ts>
struct OuterParent {
   template <Ts&...>
   struct Inner {
   };
};
template <int... Is>
struct Outer:OuterParent<Tag<Is>...> {
};
int main() {
   Outer<0>::Inner<w> f;
}

最新更新