在下面的代码片段中,我可以理解(从 §3.3.2/6 第二个要点)注入(inject)了声明 struct B* p;
中的名称 B
作为类名进入全局命名空间。
struct A {
// struct B{};
int B;
struct B* p;
};
void f(B&) {}
int main()
{
A a;
f(*a.p);
}
§3.3.2/6:
The point of declaration of a class first declared in an elaborated-type-specifier is as follows:
for a declaration of the form
class-key attribute-specifier-seq opt identifier;
the identifier is declared to be a class-name in the scope that contains the declaration, otherwise
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 3.4.4 and 7.1.6.3. — end note ]
但是,如果我取消注释 struct A
中 struct B{};
的定义,我之前所说的关于注入(inject)名称 B
进入全局命名空间,不再发生,因为代码无法编译。我相信这与上面的单词 first(强调我的)有关,因为现在 class-name B
,在声明 struct B* p;
不再是它的第一个声明在其声明区域。我这样说对吗?
假设我的解释是正确的,为什么在这种情况下 class-name B
没有被注入(inject)全局命名空间?请注意,在这种情况下,嵌套类 struct B{};
将隐藏在 A 中,即,即使我们将函数 f
的声明更改为 void f (A::B&)
代码无法编译。
还有一点我不太清楚:是什么让实现者决定在第二个要点中将类名注入(inject)到包含详细类型说明符的命名空间或 block 作用域中多于?也就是说,为什么他们不将类名声明留在类范围内?
最佳答案
你是对的,§3.3.2/6 中的 first 关键字也是以下原因:
struct A {
struct B *p;
struct B{};
int b;
};
void f(B* arg) {
std::cout << std::is_same<decltype(arg), A::B*>::value; // not the same type
}
int main()
{
A a;
f(a.p);
}
why is it that the class-name B is not injected in the global namespace in this case?
正如 dyp 指出的那样,[basic.lookup.elab]/2 解释说 3.3.2 仅在找不到以前的声明
的情况下执行If the elaborated-type-specifier is introduced by the class-key and this lookup does not find a previously declared type-name, or if the elaborated-type-specifier appears in a declaration with the form:
class-key attribute-specifier-seqopt identifier ;
elaborated-type-specifier is a declaration that introduces the class-name as described in 3.3.2.the
最后我追踪到这种行为可能是从 C99 6.7.2.3/p8 继承而来
If a type specifier of the form
struct-or-union identifier
occurs other than as part of one of the above forms, and no other declaration of the identifier as a tag is visible, then it declares an incomplete structure or union type, and declares the identifier as the tag of that type.113)
113) A similar construction with enum does not exist.
关于c++ - 我对 §3.3.2/6 中的单词 'first' 的解释是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26168445/