首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Qualified name lookup

合资格Name是出现在范围解析运算符右侧的名称。::28%也见合格标识符29%。限定名可指。

  • 类成员%28包括静态和非静态函数、类型、模板等
  • 命名空间成员%28,包括另一个命名空间%29
  • 枚举器

如果左边没有任何东西的话::,查找只考虑全局命名空间范围%28中的声明或使用声明29%。这使得即使这些名称被本地声明所隐藏,也有可能提及这些名称:

二次

代码语言:javascript
复制
#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的另一个查询。::在该名称的左侧,只考虑名称空间、类类型、枚举和专门化为类型的模板:

二次

代码语言:javascript
复制
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类或命名空间的范围内执行的:

二次

代码语言:javascript
复制
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,该标识符在与左方名称相同的范围内查找。::

二次

代码语言:javascript
复制
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,相同的语法解析为注入的类名:

二次

代码语言:javascript
复制
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)

二次

限定名查找可用于访问嵌套声明或派生类隐藏的类成员。对限定成员函数的调用从来都不是虚拟的。

二次

代码语言:javascript
复制
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 }二次另见
  • 非限定名查找
  • 范围
  • 参数相关查找
  • 模板参数推导
  • 过载分辨率
代码语言:txt
复制
 ? cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com