Namespaces
Variants

Name lookup

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

名称查找是当程序中出现某个 名称 时,将其与引入该名称的 声明 相关联的过程。

例如,要编译 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 "struct hack" 不适用于类作用域(破坏C兼容性) 适用
CWG 2218 C++98 非函数(模板)名称的查找无法关联
多个声明,即使它们声明的是同一实体
允许

另请参阅

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