命名空间
变体
操作

名称查找

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句(循环)
for
范围 for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (在 C++17* 中弃用)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
 
 

名称查找是指当程序中遇到名称时,将其与引入它的声明关联的过程。

例如,要编译 std::cout << std::endl;,编译器执行以下操作

  • 对名称 std 进行非限定名查找,这会在头文件 <iostream> 中找到命名空间 std 的声明
  • 对名称 cout 进行限定名查找,这会在命名空间 std 中找到变量声明
  • 对名称 endl 进行限定名查找,这会在命名空间 std 中找到函数模板声明
  • 对名称 operator<< 同时进行实参依赖查找,这会在命名空间 std 中找到多个函数模板声明,并对名称 std::ostream::operator<< 进行限定名查找,这会在类 std::ostream 中找到多个成员函数声明。

对于函数和函数模板名称,名称查找可以将多个声明与同一名称关联,并且可以从实参依赖查找中获取其他声明。模板实参推导也可能适用,并且声明集会传递给重载决议,后者会选择将要使用的声明。 成员访问规则(如果适用)仅在名称查找和重载决议之后才考虑。

对于所有其他名称(变量、命名空间、类等),名称查找只有在它们声明相同的实体时才能关联多个声明,否则它必须生成单个声明才能使程序编译。在作用域中查找名称会找到该名称的所有声明,但有一个例外,称为“结构体 hack”或“类型/非类型隐藏”:在同一作用域内,名称的某些出现可能引用类/结构体/联合体/枚举的声明,该声明不是 typedef,而同一名称的所有其他出现要么都引用相同的变量、非静态数据成员或枚举器,要么都引用可能重载的函数或函数模板名称。在这种情况下,没有错误,但类型名称对查找是隐藏的(代码必须使用详细类型说明符才能访问它)。

[编辑] 查找的类型

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

否则,请参阅

[编辑] 缺陷报告

以下行为变更缺陷报告已追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
CWG 2063 C++98 “结构体 hack”不适用于类作用域(破坏 C 兼容性) 已应用
CWG 2218 C++98 非函数(模板)名称的查找可能无法关联
多个声明,即使它们声明相同的实体
允许

[编辑] 参见

C 文档 关于 查找和命名空间