名称查找
来自 cppreference.cn
名称查找是指程序中遇到名称时,将其与引入该名称的声明关联的过程。
例如,要编译 std::cout << std::endl;,编译器会执行:
- 对名称
std
进行非限定名称查找,这会在头文件 <iostream> 中找到命名空间 std 的声明。 - 对名称
cout
进行限定名称查找,这会在命名空间std
中找到一个变量声明。 - 对名称
endl
进行限定名称查找,这会在命名空间std
中找到一个函数模板声明。 - 对名称
operator<<
同时进行实参依赖查找(它在命名空间std
中找到多个函数模板声明)和对名称 std::ostream::operator<< 进行限定名称查找(它在类 std::ostream 中找到多个成员函数声明)。
对于函数和函数模板名称,名称查找可以将多个声明与同一个名称关联,并可能从实参依赖查找中获取额外的声明。模板实参推导也可能适用,声明集被传递给重载决议,重载决议会选择将要使用的声明。如果适用,成员访问规则仅在名称查找和重载决议之后考虑。
对于所有其他名称(变量、命名空间、类等),名称查找只有在它们声明同一实体时才能关联多个声明,否则它必须生成单个声明才能使程序编译。在作用域中查找名称会找到该名称的所有声明,但有一个例外,称为“结构体黑客”或“类型/非类型隐藏”:在同一作用域内,名称的一些出现可能指代不是typedef的类/结构体/联合体/枚举体的声明,而同一名称的所有其他出现要么都指代同一个变量、非静态数据成员或枚举器,要么都指代可能重载的函数或函数模板名称。在这种情况下,没有错误,但类型名称被从查找中隐藏(代码必须使用详细类型说明符才能访问它)。
[编辑] 查找类型
如果名称紧跟在作用域解析运算符 ::
的右侧,或者可能在 ::
之后跟着消歧关键字 template
,请参见:
否则,请参见:
- (对于函数名称,这包括实参依赖查找)
[编辑] 缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 发布时的行为 | 正确的行为 |
---|---|---|---|
CWG 2063 | C++98 | "结构体黑客"不适用于类作用域(破坏C兼容性) | 已应用 |
CWG 2218 | C++98 | 非函数(模板)名称的查找无法关联 多个声明,即使它们声明的是同一个实体 |
允许 |
[编辑] 另请参见
C 文档 关于 查找和命名空间
|