在模板上下文中,foo(void)是否等同于foo()?

4

由于C语言的历史原因,在C++中,以下定义是等效的:

void foo() {}
void foo(void) {}

当foo位于模板类中时会发生什么?例如:

template <typename T> struct C { void foo(T) {} };

int main()
{ C<void> c;
  c.foo();
}

MSVC (19.30) 接受这段代码,但是 gcc (11.2) 拒绝它。

看起来编译器对于当 T = voidfoo(T) 是否等同于 foo() 存在不同的看法。

哪一个是正确的呢?


我认为将void作为模板参数是无效的。可能是重复的问题:在C++中使用'void'模板参数 - 但自那个问题/答案发布以来(超过9年),事情可能已经发生了变化。 C ++11标准在此答案中引用。 - Adrian Mole
也许相关的是:如何在这里将不完整类型用作向量的模板参数? 此外,根据标准:类型 cv void 是一种无法完成的不完整类型; - Adrian Mole
1
void 作为类模板参数是被允许的,有很多代码使用了它。一个非模板函数声明带有一个(单一的)void 参数类型也是被允许的,但与空参数列表等效。问题在于当 void 不是字面上的关键字,而是模板参数的值时,是否允许将其作为函数参数类型。 - user1958486
好的。我表达不够准确。我想说的是,void不能作为一个模板参数类型(我认为)。 - Adrian Mole
我在第一条评论中提供的答案(James McNellis所写)中引用的C++11标准摘录似乎完全涵盖了你的情况。你的void参数不是非依赖性的。我真的看不出那个答案为什么不能回答这个问题,所以我将其视为重复问题并关闭。 - Adrian Mole
1个回答

3
规范说明(C++11 §8.3.5[dcl.func]/4):

由单个未命名的非依赖类型void参数组成的参数列表相当于空参数列表。除了这种特殊情况外,参数不能具有cv void类型。

由于您的情况具有依赖类型(取决于T),因此gcc是正确的。


所以,如果我正确理解了评论,对于原始问题的答案似乎是gcc正确地拒绝了代码。 - user1958486
@user1958486 是的,gcc是正确的。 - Jason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接