Qualified name lookup
限定名查找
阿合资格
Name是出现在范围解析运算符右侧的名称。::
28%也见合格标识符29%。限定名可指。
- 类成员%28包括静态和非静态函数、类型、模板等
- 命名空间成员%28,包括另一个命名空间%29
- 枚举器
如果左边没有任何东西的话::
,查找只考虑全局命名空间范围%28中的声明或使用声明29%。这使得即使这些名称被本地声明所隐藏,也有可能提及这些名称:
二次
#include <iostream>
int main()
{
struct std{};
std::cout << "fail\n"; // Error: unqualified lookup for 'std' finds the struct
::std::cout << "ok\n"; // OK: ::std finds the namespace std
}
二次
之前,可以对右方的名称执行名称查找。::
,则必须完成对其左侧名称%28的查找,除非解密型表达式被使用,或者左边的%29没有任何内容。此查找可能是限定的,也可能是不合格的,这取决于是否有%27s的另一个查询。::
在该名称的左侧,只考虑名称空间、类类型、枚举和专门化为类型的模板:
二次
struct A {
static int n;
};
int main() {
int A;
A::n = 42; // OK: unqualified lookup of A to the left of :: ignores the variable
A b; // error: unqualified lookup of A finds the variable A
}
二次
当限定名用作报关员,然后不合格查找在该限定名后面的同一个声明器中使用的名称,而不是它前面的名称,是在成员%27s类或命名空间的范围内执行的:
二次
class X { };
constexpr int number = 100;
struct C {
class X { };
static const int number = 50;
static X arr[number];
};
X C::arr[number], brr[number]; // Error: look up for X finds ::X, not C::X
C::X C::arr[number], brr[number]; // OK, size of arr is 50, size of brr is 100
二次
如果::
后面跟着字符。~
,然后是标识符%28,即指定析构函数或伪析构函数%29,该标识符在与左方名称相同的范围内查找。::
二次
struct C { typedef int I; };
typedef int I1, I2;
extern int *p, *q;
struct A { ~A( };
typedef A AB;
int main() {
p->C::I::~I( // the name I after ~ is looked up in the same scope as I before ::
// (that is, within the scope of C, so it finds C::I)
q->I1::~I2( // The name I2 is looked up in the same scope as I1
// that is, from the current scope, so it finds ::I2
AB x;
x.AB::~AB( // The name AB after ~ is looked up in the same scope as AB before ::
// that is, from the current scope, so it finds ::AB
}
二次
Enumerators If the lookup of the left-hand side name comes up with an enumeration (either scoped or unscoped), the lookup of the right-hand side must result in an enumerator that belongs that enumeration, otherwise the program is ill-formed. | (since C++11) |
---|
班级成员
如果在查找左侧名称时出现类/结构或联合名称,则在::
在该类%28的作用域中查找,因此可能会找到该类成员或其基%29的声明,但有下列例外情况。
- 如上文所述,析构函数在位于::%29左边的名称范围中查找。
- 中的转换类型id。用户定义转换函数名首先在类的范围中查找。如果找不到,则在当前范围中查找该名称。转换类型id必须在两个作用域中表示相同的类型。
- 模板参数中使用的名称在当前作用域%28中查找,而不是在模板名%29的范围中查找。
- 人名使用-声明还考虑由同一作用域中声明的变量、数据成员、函数或枚举数的名称隐藏的类/枚举名称。
如果右手边::
名称与左侧命名相同的类,名称指定构造器那个班的。此类限定名只能用于构造函数的声明和使用-声明为了继承构造函数.在那些忽略函数名称的查找中,即在查找::
,当在精化类型说明符,或基说明符%29,相同的语法解析为注入的类名:
二次
struct A { A( };
struct B : A { B( };
A::A() { } // A::A names a constructor, used in a declaration
B::B() { } // B::B names a constructor, used in a declaration
B::A ba; // B::A names the type A (looked up in the scope of B)
A::A a; // Error, A::A does not name a type
struct A::A a2; // OK: lookup in elaborated type specifier ignores functions
// so A::A simply names the class A as seen from within the scope of A
// (that is, the injected-class-name)
二次
限定名查找可用于访问嵌套声明或派生类隐藏的类成员。对限定成员函数的调用从来都不是虚拟的。
二次
struct B { virtual void foo( };
struct D : B { void foo() override; };
int main()
{
D x;
B& b = x;
b.foo( // calls D::foo (virtual dispatch)
b.B::foo( // calls B::foo (static dispatch)
}
二次
命名空间成员
如果左边的名字::
引用名称空间,或者如果在::
%28--在这种情况下,它引用全局命名空间%29,该名称显示在::
在名称空间的作用域中查找,除了。
- 模板参数中使用的名称在当前范围中查找。二次namespace N { template<typename T> struct foo {}; struct X {}; } N::foo<X> x; // error: X is looked up as ::X, not as N::X二次范围内的限定查找。命名空间N首先考虑位于N中的所有声明。内联命名空间成员成N%28,并在其内联命名空间成员%29中传递。如果在该集合中没有声明,那么它将考虑所有命名空间中的声明。使用-指令发现于N的所有传递内联命名空间成员N.这些规则以递归方式适用:二次int x; namespace Y { void f(float void h(int } namespace Z { void h(double } namespace A { using namespace Y; void f(int void g(int int i; } namespace B { using namespace Z; void f(char int i; } namespace AB { using namespace A; using namespace B; void g( } void h() { AB::g( // AB is searched, AB::g found by lookup and is chosen AB::g(void) // (A and B are not searched) AB::f(1 // First, AB is searched, there is no f // Then, A, B are searched // A::f, B::f found by lookup (but Y is not searched so Y::f is not considered) // overload resolution picks A::f(int) AB::x++; // First, AB is searched, there is no x // Then A, B are searched. There is no x // Then Y and Z are searched. There is still no x: this is an error AB::i++; // AB is searched, there is no i // Then A, B are searched. A::i and B::i found by lookup: this is an error AB::h(16.8 // First, AB is searched: there is no h // Then A, B are searched. There is no h // Then Y and Z are searched. // lookup finds Y::h and Z::h. Overload resolution picks Z::h(double) }二次允许不止一次地找到同一声明:二次namespace A { int a; } namespace B { using namespace A; } namespace D { using A::a; } namespace BD { using namespace B; using namespace D; } void g() { BD::a++; // OK: finds the same A::a through B and through D }二次另见
- 非限定名查找
- 范围
- 参数相关查找
- 模板参数推导
- 过载分辨率
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。