名字查找

< cpp‎ | language

名字查找,是当程序中出现一个名字时,将其与引入它的声明联系起来的过程。

例如,为编译 std::cout << std::endl;,编译器进行了:

  • 名字 std 的无限定的名字查找,找到了头文件 <iostream> 中的命名空间 std 的声明
  • 名字 cout 的有限定的名字查找,找到了命名空间 std 中的一个变量声明
  • 名字 endl 的有限定的名字查找,找到了命名空间 std 中的一个函数模板声明
  • 名字 operator <<实参依赖查找,找到了命名空间 std 中的多个函数模板声明;和名字 std::ostream::operator<< 的有限定名字查找,找到了 std::ostream 类中的多个成员函数声明

对于函数和函数模板的名字,名字查找可以将同一个名字和多个声明联系起来,而且可能从实参依赖查找中得到额外的声明。还会进行模板实参推导,并将声明的集合交给重载决议,由它选择所要使用的那个声明。成员访问的规则只会在名字查找和重载解析之后才被考虑,如果适用的话。

对所有其他的名字(变量,命名空间,类等等)的名字查找,程序只有在只产生单个声明的情况下才能编译。对某个作用域中的名字进行查找将寻找到该名字的所有声明,但有一种例外,被称作“ struct hack ”或“类型/非类型名字隐藏”:同一作用域中,某个名字的一些出现可以代表非 typedef 的 class/struct/union/enum 声明,而其他出现要么全都代表同一个变量、非静态数据成员 (C++14 起)或者枚举项,要么全都代表可能重载的函数或函数模板名。此情况下无错误,但类型名在查找中被隐藏(代码必须用详述类型说明符来访问它)。

查找的类型

如果名字紧跟在作用域解析运算符 ::,或可能跟在 :: 之后的消歧义关键词 template 的右侧,参见

否则,请参见

参阅