请考虑以下示例:
#include <iostream>
void foo(class B, B *b);
B *c; //OK
int main(){ }
Run Code Online (Sandbox Code Playgroud)
标准 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是宣言员的结尾.但该名称在全球范围内可见.为什么?
您在3.3.2 [basic.scope.pdecl]/p7中引用了错误的项目符号.该class B声明中的foo不是形式的class-key attribute-specifier-seq_opt identifier;-没有分号.
相反,第二个子弹适用:
对于表单的详细类型说明符
类密钥标识符
如果在命名空间作用域中定义的函数的decl-specifier-seq 或parameter-declaration-clause中使用了elaborated-type-specifier,则在包含声明的命名空间中将标识符声明为类名.否则,除了作为友元声明之外,标识符在包含声明的最小命名空间或块范围中声明.
因此,示例中的详细类型说明符 class B在包含声明的名称空间中声明B为类名,foo即全局名称空间.