我在理解 [basic.scope.pdecl]/7 时遇到一些困难
I'm having some difficulty understanding [basic.scope.pdecl]/7
The point of declaration of a class first declared in an
elaborated-type-specifier is as follows:
(7.1) for a declaration of the form
class-key attribute-specifier-seqopt identifier ;
the identifier is declared to be a class-name in the scope that contains the declaration, otherwise
(7.2) for an elaborated-type-specifier of the form
class-key identifier
if the elaborated-type-specifier is used in the decl-specifier-seq
or
parameter-declaration-clause of a function defined in namespace
scope, the identifier is
declared as a class-name in the namespace that contains the declaration; otherwise,
except as a friend
declaration, the identifier is declared in the smallest namespace or
block scope that contains the declaration. [ Note: These rules also apply within templates.
— end note ] [ Note: Other forms of elaborated-type-specifier do not declare a new
name, and therefore must refer to an existing type-name. See [basic.lookup.elab] and
[dcl.type.elab].— end note ]
考虑上面的情况 (7.2),其中 elaborated-type-specifier 用于 decl-specifier-seq 参数声明子句 在命名空间范围内定义的函数。这将如何与这个 elaborated-type-specifier 必须是 class 在其命名空间中的 first 声明这一事实相协调?
考虑下面的示例 (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);
}
文件other.cc
:
#include<iostream>
struct S{
int i = 1;
};
void f(struct S& s) { std::cout << s.i << '\n'; }
S s;
请注意,上面的代码可以正确编译和执行,但是 parameter-declaration-clause 中的 elaborated-type-specifer函数 f
不是全局命名空间中的第一个。
假设我对 [basic.scope.pdecl]/7 的解释是正确的,我想看一个例子来说明上面第 (7.2) 段的应用,其中提到的声明是 first 在其命名空间中。
I would like to see an example showing the application of paragraph (7.2) above, where the alluded declaration would be the first in its namespace.
简单地说:
namespace ns {
// declares S into ns as per [basic.scope.pdecl]
void f(struct S&);
}
extern ns::S s;
//extern ::S s; // not declared
此处 struct S
首先在命名空间范围内定义的函数的参数声明子句的详细类型说明符中声明,形式为 class-key identifier
,因此 [basic.scope.pdecl]/7.2 适用并且 struct S
在声明函数的命名空间 ns
中声明。
you'll have to use an object of class S
in your function f
这是一个example:
// ... continuing from previous example ...
namespace ns {
struct S {
int i;
};
void f(S& s) {
std::cout << s.i;
}
}
作为奖励,一个例子中 class 没有首先在 elaborated-type-specifier 中声明,因此引用的规则不适用:
struct S;
namespace ns {
void f(struct S&); // refers to ::S
}
//extern ns::S s; // not declared
extern ::S s;
这里elaborated-type-specifier不是struct S
的第一个声明,所以[basic.scope.pdecl]/7不适用,没有class声明到命名空间。
if we eliminate the first declaration struct S;
on the top, the code doesn't compile !!
那是因为你仍然需要在使用之前声明一个名称。
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);
}
Note that the code above compiles and executes correctly, but the elaborated-type-specififer in the parameter-declaration-clause of function f
is not the first in the global namespace.
我不明白你在这里想表达的意思。因为它不是第一个,所以没有声明名称并且 [basic.scope.pdecl]p7 不适用。
I would like to see an example showing the application of paragraph (7.2) above, where the alluded declaration would be the first in its namespace.
auto addrof(struct S& s) { // First declaration
return &s;
}
int get(struct T&); // First declaration
The point of declaration of a class first declared in an elaborated-type-specifier is as follows:
(7.1) for a declaration of the form
class-key attribute-specifier-seqopt identifier
;
the identifier is declared to be a class-name in the scope that contains the declaration, otherwise
(7.2) for an elaborated-type-specifier of the form
class-key identifier
if the elaborated-type-specifier is used in the decl-specifier-seq or
parameter-declaration-clause of a function defined in namespace scope, the identifier is declared as a class-name in the namespace that contains the declaration; otherwise, except as a friend declaration, the identifier is declared in the smallest namespace or block scope that contains the declaration. [ Note: These rules also apply within templates. — end note ] [ Note: Other forms of elaborated-type-specifier do not declare a new name, and therefore must refer to an existing type-name. See [basic.lookup.elab] and [dcl.type.elab].— end note ]
考虑上面的情况 (7.2),其中 elaborated-type-specifier 用于 decl-specifier-seq 参数声明子句 在命名空间范围内定义的函数。这将如何与这个 elaborated-type-specifier 必须是 class 在其命名空间中的 first 声明这一事实相协调?
考虑下面的示例 (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);
}
文件other.cc
:
#include<iostream>
struct S{
int i = 1;
};
void f(struct S& s) { std::cout << s.i << '\n'; }
S s;
请注意,上面的代码可以正确编译和执行,但是 parameter-declaration-clause 中的 elaborated-type-specifer函数 f
不是全局命名空间中的第一个。
假设我对 [basic.scope.pdecl]/7 的解释是正确的,我想看一个例子来说明上面第 (7.2) 段的应用,其中提到的声明是 first 在其命名空间中。
I would like to see an example showing the application of paragraph (7.2) above, where the alluded declaration would be the first in its namespace.
简单地说:
namespace ns {
// declares S into ns as per [basic.scope.pdecl]
void f(struct S&);
}
extern ns::S s;
//extern ::S s; // not declared
此处 struct S
首先在命名空间范围内定义的函数的参数声明子句的详细类型说明符中声明,形式为 class-key identifier
,因此 [basic.scope.pdecl]/7.2 适用并且 struct S
在声明函数的命名空间 ns
中声明。
you'll have to use an object of class
S
in your functionf
这是一个example:
// ... continuing from previous example ...
namespace ns {
struct S {
int i;
};
void f(S& s) {
std::cout << s.i;
}
}
作为奖励,一个例子中 class 没有首先在 elaborated-type-specifier 中声明,因此引用的规则不适用:
struct S;
namespace ns {
void f(struct S&); // refers to ::S
}
//extern ns::S s; // not declared
extern ::S s;
这里elaborated-type-specifier不是struct S
的第一个声明,所以[basic.scope.pdecl]/7不适用,没有class声明到命名空间。
if we eliminate the first declaration
struct S;
on the top, the code doesn't compile !!
那是因为你仍然需要在使用之前声明一个名称。
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);
}
Note that the code above compiles and executes correctly, but the elaborated-type-specififer in the parameter-declaration-clause of function
f
is not the first in the global namespace.
我不明白你在这里想表达的意思。因为它不是第一个,所以没有声明名称并且 [basic.scope.pdecl]p7 不适用。
I would like to see an example showing the application of paragraph (7.2) above, where the alluded declaration would be the first in its namespace.
auto addrof(struct S& s) { // First declaration
return &s;
}
int get(struct T&); // First declaration