在线文档教程
C++
语言 | Language

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。

http://en.cppreference.com/w/cpp/language/Quantity[医]查找