【发布时间】:2017-02-01 13:57:18
【问题描述】:
从[temp.variadic](工作草案)看来,在定义另一个模板类或函数的参数列表时,可以扩展参数包。
考虑以下类:
template<typename... T>
struct S {
template<T... I>
void m() {}
};
int main() {
S<int, char> s;
// ...
}
目的是捕获用于特化模板类S的类型,并使用它们为成员方法m(T)定义非类型参数的参数列表当然,仅限于几种类型,但这不是问题的论点)。
这是合法的代码吗?我可以按照我使用的方式使用参数包还是我误解了标准(很确定确实如此)?
为了给问题添加更多细节,以下是一些主要编译器的实验结果:
s.m<0, 'c'>():clang v3.9 编译它,GCC v6.2 和 GCC v7 返回错误。s.m<0>();:clang v3.9 编译它,GCC v6.2 返回错误,GCC v7 使用 ICE 停止编译。s.m<>();: clang v3.9, GCC v6.2 和 GCC v7 编译它没有错误。
至少,编译器似乎和我一样困惑。
【问题讨论】:
-
是的,它是有效的,甚至可以是空的:stackoverflow.com/questions/32540178/…
-
GCC 在可变参数模板方面并不聪明。
-
@JohannesSchaub-litb 不应该因此拒绝
s.m<0>();吗?在这种情况下,两个编译器都出错了? -
其他 SO 用户告诉我,语义是“T...I”意味着 T 被扩展,“I”成为 int 和 char 值的包。 (即异构非类型模板参数包)。我不明白为什么 clang 接受的“I”参数少于两个参数。话虽如此,这么多年过去了,我仍然认为我还没有完全理解这个特殊案例的规则。
-
@JohannesSchaub-litb 实际上我只是在阅读它们。因此this 代码也有效吗?如果你能花一分钟时间,我会接受你的回答。我猜它几乎来自同一个问题。
标签: c++ gcc clang language-lawyer variadic-templates