博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qualified name lookup
阅读量:4963 次
发布时间:2019-06-12

本文共 8939 字,大约阅读时间需要 29 分钟。

Qualified name lookup

Unqualified identifiers(omitted)

Besides suitably declared identifiers, the following can be used in expressions in the same role:

  • an overloaded operator name in function notation, such as operator+ or operator new
  • a user-defined conversion function name, such as operator bool
  • a user-defined literal operator name, such as operator "" _km
  • a template name followed by its argument list, such as MyTemplate<int>
  • the character ~ followed by a class name, such as ~MyClass
  • the character ~ followed by a decltype specifier, such as ~decltype(str)

Together with identifiers they are known as unqualified id-expressions.

Qualified identifiers

A qualified id-expression is an unqualified id-expression prepended by a scope resolution operator ::, and optionally, a sequence of enumeration, (since C++11)class or namespace names or decltype expressions (since C++11) separated by scope resolution operators.

std::string::npos::tolowerstd::coutboost::signals2::connection

Qualified name lookup

A qualified name is a name that appears on the right hand side of the scope resolution operator :: (see also qualified identifiers). A qualified name may refer to a

  • (including static and non-static function,types,templates.etc)
  • (including another namespace)

If there is nothing on the left hand side of the ::, the lookup considers only declarations made in the global namespace scope(or introduced into the global namespace by a using declaration).

Example hided std namespace

#include 
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,global namespace }

Before name lookup can be performed for the name on the right hand side of ::, lookup must be completed for the name on its left hand side (unless a decltype expression is used, or there is nothing on the left). This lookup, which may be qualified or unqualified, depending on whether there's another :: to the left of that name, considers only namespaces, class types, enumerations, and templates whose specializations are types:

在name lookup执行之前,要检查name的完整性,::右边的name在左边的scope中,则是qualified,否则为unqualified。

::右边的名字必须在::左边的namespace or class types or enumeration or templates whose specializations are types 中。

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}

When a qualified name is used as a declarator, then lookup of all names used in the same declarator that follow that qualified name, but not the names that precede it, is performed as if qualified the same way:

class X { };constexpr int number = 100;class C {  class X { };  static const int number = 50;  static X arr[number];};X C::arr[number], brr[number];   // Error  // Every name in the declarator "C::arr[number]" after "C::arr"  // is looked up within C::, but the names before C::arr are unaffected,  // The names in the second declarator ("brr[number]") are also unaffected  // equivalent to:  // "::X C::arr[C::number], brr[::number]"  // 这与声明 int *a,b;一样,a是一个int*类型,而b是一个int类型   // 因为在X类型中找不到C::X C::arr[number], brr[number]; // Compiles, size of arr is 50, size of brr is 100

destructor的lookup

If the name on the right hand side of :: is a destructor or pseudo-destructor (that is, the character ~ followed by an identifier), that identifier is looked up in the same scope as the name on the left hand side of ::.

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}

Enumerations

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.

Class members

If the lookup of the left hand side name comes up with a class/struct or union name, the name on the right hand side of :: is looked up in the scope of that class (and so may find a declaration of a member of that class or of its base), with the following exceptions

  • destructor name is looked up as described above (in the scope of the name to the left of ::)
  • user-defined conversion function name is TODO
  • names used in template argument are looked up in the current scope(not int the scope of template name)
  • names in using-declarations also consider class/enum names that are hidden in current scope

编译器中constructor的产生

If the right hand side of :: names the same class as the left hand side, the name designates the constructor of that class.
Such qualified name can only be used in a declaration of a constructor and in the for an .

In those lookups where function names are ignored (that is, when looking up a name on the left of ::, when looking up a name in elaborated type specifier, or base specifier), the same syntax resolves to the injected-class-name:

struct A { A(); };struct B : A { B(); };A::A() { } // A::A names a constructor, used in a declarationB::B() { } // B::B names a constructor, used in a declarationB::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)

Qualified name lookup can be used to access a class member that is hidden by a nested declaration or by a derived class. A call to a qualified member function is never virtual

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)}

Namespace members

  1. If the name on the left of :: refers to a namespace or if there is nothing on the left of :: (in which case it refers to the global namespace), the name that appears on the right hand side of :: is looked up in the scope of that namespace, except that
  • names used in template arguments are looked up int the current scope.
namespace N {   template
struct foo {}; struct X {};}N::foo
x; // error: X is looked up as ::X, not as N::X

在namespace N内的qualified lookup首先会考虑到位于N内的和N内的inline namespace 成员(具有传递性)。

  1. Qualified lookup within the scope of a namespace N first considers all declarations that are located in N and all declarations that are located in the inline namespace members of N (and, transitively, in their inline namespace members).

之后才会考虑到使用use-derectives引入的namespace和inline namespace(使用use-derectives引入的namespace)

  1. If there are no declarations in that set then it considers declarations in all namespaces named by using-directives found in N and in all transitive inline namespace members of N. The rules are applied recursively:
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++;  // ERROR   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++;  // ERROR    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)}
  1. It is allowed for the same declaration to be found more than once:
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}

转载于:https://www.cnblogs.com/Wojoin/p/5175851.html

你可能感兴趣的文章
为什么回车叫做回车?
查看>>
WebView详解
查看>>
Delphi中MsComm控件的安装使用
查看>>
LeetCode:Remove Element
查看>>
Linq中Take、TakeWhile、Skip、SkipWhile的比较
查看>>
mac安装mysql的两种方法(含配置)
查看>>
Python模块学习------Matplotlib
查看>>
模板模式
查看>>
qt5 移植 交叉编译出现错误
查看>>
jQuery使用简单示例 validate 插件
查看>>
表单2-下拉菜单
查看>>
java 12-5 StringBuffer的几个案例
查看>>
centos6的JDK安装
查看>>
hdu1384Intervals(差分约束)
查看>>
无论后来怎样,你应该依然坚持你的初衷
查看>>
使用程序修改系统(IE)代理设置
查看>>
Eclipse常用快捷键与IDEA中的对比.
查看>>
memortstream Base64编码和filestream base64编码不同
查看>>
2016.3.9-3.10(java集合框架)
查看>>
ptyhon之路day4-称空间与作用域及函数2高阶函数
查看>>