在函数声明中进行类声明

3
考虑以下实例:
#include <iostream>

void foo(class B, B *b); 

B *c; //OK

int main(){ }

演示

标准N4296::3.3.2/7.1 [basic.scope.pdecl]

对于形式为

class-key attribute-specifier-seqopt identifier;

的声明,该标识符在包含声明的作用域中被声明为类名。

但是根据N4296:3.3.4/1 [basic.scope.proto]

在函数声明中,或在任何函数声明符(除函数定义的声明符(8.4)之外)中,参数名称(如果提供)具有函数原型作用域,该作用域在最近的封闭函数声明符结束时终止。

因此,class B应该已经引入了函数原型作用域。并且B的作用域应该一直持续到foo的声明符结束。但是这个名称在全局作用域中可见。为什么?


我不知道,但GCC 4.7也接受这个。我真的很好奇你是如何首先想出这个结构的! - John Zwinck
第一个引号不适用。没有分号。 - T.C.
1个回答

6
您在3.3.2 [basic.scope.pdecl]/p7中引用了错误的项目。声明 foo 中的 class B 不符合形式 class-key attribute-specifier-seq_opt identifier;,即没有分号。
相反,适用第二个项目:
对于形式为 class-key identifier限定类型名,如果限定类型名用于函数在命名空间范围内定义的 decl-specifier-seqparameter-declaration-clause,则将该标识符声明为所包含声明的命名空间中的类名;否则,在不作为友元声明的情况下,将该标识符声明在包含该声明的最小命名空间或块范围内。
因此,在您的示例中,class B限定类型名B声明为一个类名,它位于包含 foo 声明的命名空间中——即全局命名空间。

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