我在理解[basic.scope.pdecl] / 7时遇到了一些困难

Ayr*_*osa 6 c++ forward-declaration language-lawyer

[basic.scope.pdecl] / 7

首先elaborated-type-specifier中声明的类的声明要点如下:

(7.1)声明形式

          class-key attribute-specifier-seq opt 标识符 ;

         的识别符被声明为一个类名称在包含声明的范围,否则

(7.2)用于阐述型说明符的形式的

          类键 标识符

         如果在命名空间范围内定义的函数的decl-specifier-seqparameter-declaration-clause中使用了elaborated-type-specifier,则标识符将在包含该声明的命名空间中声明为类名;否则,除作为好友声明外,标识符在包含该声明的最小名称空间或块范围中声明。[?注意:这些规则也适用于模板。-?end note?] [?注:其他形式的 elaborated-type-specifier不会声明新名称,因此必须引用现有的type-name
         。请参阅[basic.lookup.elab]和[dcl.type.elab]。-?尾注?]

考虑上面的情况(7.2),其中在命名空间范围中定义的函数的参数声明子句decl-specifier-seq中使用了elaborated-type-specifier。这个精巧的类型说明符必须是该类在其命名空间中的第一个声明,这一事实如何与之相协调?

考虑下面的示例(demo):

档案prog.cc

struct S;
extern S s;
int S;
void f(struct S&);     // The elaborated-type-specififer `struct S` is not
                       // the first declaration in the global namespace and
                       // if we eliminate the first declaration `struct S;` 
                       // on the top, the code doesn't compile !!
int main(){
    f(s);
}
Run Code Online (Sandbox Code Playgroud)

档案other.cc

#include<iostream>
struct S{
    int i = 1;
};
void f(struct S& s) { std::cout << s.i << '\n'; }
S s;
Run Code Online (Sandbox Code Playgroud)

请注意,上面的代码可以正确编译和执行,但是函数的参数声明子句精心设计的类型说明符不是全局命名空间中的第一个。f

假设我对[basic.scope.pdecl] / 7的解释是正确的,我想看一个示例,显示上面第(7.2)段的应用,其中所引用的声明将是其命名空间中的第一个声明。

Rak*_*111 4

struct S;如果我们删除顶部的第一个声明,代码将无法编译!

那是因为在使用名称之前您仍然需要声明它。

int S;
void f(struct S&); 
extern struct S s; // If you write this line before then it
                   // will not compile.
                   // The name still needs to be declared
                   // before you use it.
// If you drop the `int S` above, then the following
// will also compile, since S has already been declared
// extern S s2;

int main(){
    f(s);
}
Run Code Online (Sandbox Code Playgroud)

请注意,上面的代码可以正确编译和执行,但函数的参数声明子句中的详细类型说明符不是全局命名空间中的第一个。f

我不明白你想在这里表达的观点。由于它不是第一个,因此没有声明名称并且 [basic.scope.pdecl]p7 不适用。

我希望看到一个示例,显示上面第 (7.2) 段的应用,其中提到的声明将是其名称空间中的第一个声明。

auto addrof(struct S& s) { // First declaration
    return &s;
}
int get(struct T&); // First declaration
Run Code Online (Sandbox Code Playgroud)