名字查找
名字查找,是当程序中出现一个名字时,将其与引入它的声明联系起来的过程。
例如,为编译 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
的右侧,参见
否则,请参见
- (其中对于函数名,还包括实参依赖查找)