[英]Name lookup of qualified base class
Consider this code: 考虑以下代码:
#include <iostream>
namespace D
{
struct S { S(){std::cout << "D::S\n";} };
}
struct S { S(){std::cout << "S\n";} };
struct X: D::S
{
X(): S() {} // (1)
// X(): D::S() {} // (2)
void f() { S s; }
};
int main() { X x; x.f(); }
Output from g++ is: 来自g ++的输出是:
D::S
D::S
My questions are: 我的问题是:
D::S
specifically D::S
S s;
S s;
inside f()
refer to D::S
and not ::S
? f()
内部引用D::S
而不是::S
? Within the body of the class D::S
the name S
refers to itself, obviously. 显然,在类
D::S
的内部,名称S
指向其自身。 This is called the "injected class name". 这称为“注入的类名”。 You can think of it as though there is a public member typedef in
D::S
with its own name, S
. 您可以认为它好像
D::S
有一个公共成员typedef,其名称为S
- How does (1) work - I would have though that the name of the base class is D::S specifically
(1)的工作方式-虽然我将基类的名称专门指定为D :: S
X
derives from D::S
, because you said so in the base class list of X
. X
源自D::S
,因为您在X
的基类列表中是这样说的。
A derived class has access to the names declared in a base class, so name lookup in X
first looks at its own members and its base class' members, then looks for names in the enclosing scope outside X
. 派生类可以访问在基类中声明的名称,因此
X
名称查找首先查看其自身的成员及其基类的成员,然后在X
之外的封闭范围内查找名称。 Because the injected class name S
is a member of D::S
, it gets found in X
, that's why (1) works. 由于注入的类名
S
是D::S
的成员,因此可以在X
找到它,这就是(1)起作用的原因。 The type ::S
is not found because name lookup finds the injected class name and never looks in the enclosing scope (if it did find ::S
the code wouldn't compile, because ::S
is not a base class of X
). 该类型
::S
没有找到,因为名称查找发现注入的类名和从不看在封闭范围(如果它没有找到::S
的代码将无法编译,因为::S
不是一个基类的X
) 。
As an analogy consider this example using a member typedef declared in D::S
: 作为类推,考虑使用
D::S
声明的成员typedef的示例:
namespace D {
struct S {
struct S { S(){std::cout << "D::S\n";} };
typedef S AnotherName;
};
}
struct X : D::S {
X() : AnotherName() { }
};
This works because the name AnotherName
is found in the base class, and is a synonym for the type of the base class, D::S
. 之所以
AnotherName
是因为在基类中找到了名称AnotherName
,并且该名称是基类D::S
的同义词。 The injected class name works similarly, except that the name that gets injected is the class' own name, S
, not some other name like AnotherName
. 注入的类名的工作方式类似,不同之处在于,注入的类名是该类自己的名称
S
,而不是其他名称,例如AnotherName
。
- Are (1) and (2) both required to work?
(1)和(2)都需要工作吗?
Yes. 是。
(2) works because D::S
is the fully-qualified named of S
so it refers to the same type, but using its "full name" that non-members must use to refer to the type. (2)的作品,因为
D::S
是完全合格的命名的S
所以它指的是同一类型,但使用它的“全名”非成员必须使用引用类型。
- Why does S s;
为什么S s; inside f() refer to D::S and not ::S ?
在f()内部引用D :: S而不是:: S?
Because like the constructor, f()
is a member of X
so name lookup looks inside the scope of X
(and its base classes) first, and so finds the injected class name. 因为像构造函数一样,
f()
是X
的成员,所以名称查找首先在X
(及其基类)的范围内进行,然后查找注入的类名称。 It never see the type ::S
at global scope because it finds the name S
as a member of the base class and stops looking. 它永远不会在全局范围内看到类型
::S
,因为它会找到名称S
作为基类的成员并停止查找。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.