考虑以下示例:
#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
的声明者的末尾。但该名称在全球范围内可见。为什么呢?
答案 0 :(得分:6)
您在3.3.2 [basic.scope.pdecl] / p7中引用了错误的项目符号。 class B
声明中的foo
不是class-key attribute-specifier-seq_opt identifier;
的形式 - 没有分号。
相反,第二颗子弹适用:
表格
的详细类型说明符类密钥标识符
如果在 decl-specifier-seq 中使用 elaborated-type-specifier 或命名空间中定义的函数的 parameter-declaration-clause 范围,标识符在命名空间中声明为类名 包含声明;否则,除了作为朋友 声明,标识符在最小的命名空间或 阻止包含声明的范围。
因此,示例中的 elaborated-type-specifier class B
在包含声明的命名空间中将B
声明为类名 foo
- 即全局命名空间。