嵌套名称说明符中第一个命名空间名称的名称查找
Name lookup of first namespace name in nested-name-specifier?
给定没有任何类、模板、枚举或 typedef 的翻译单元中的嵌套名称说明符A::
,如果格式正确,则标识符A
必须引用命名空间。
例如:
namespace X
{
int i;
}
int main()
{
X::i = 42; // Here X:: is a nested-name-specifier
// and X is a namespace-name
// i is looked up qualified w.r.t. X
}
在上面的例子中,A
X
,但是我的问题是关于一般情况的。
如何对A::
中的命名空间名称A
进行名称查找?
3.4 中,但我不清楚在这种情况下如何(或哪些规则(适用。
例如,A
的查找是否为非限定名称查找? 3.4.1 是否适用于它?
换句话说:在哪些命名空间中搜索名为 A
的命名空间,以及以什么顺序搜索? 您是如何从标准中得出这一结论的?
,A
是 3.4.1 的常规非限定名称查找,连续搜索包含嵌套名称说明符的范围,但只找到类和命名空间名称。例如,你可以有这个:
int main()
{
int X;
X::i = 42; // OK, int X not found.
}
http://ideone.com/NaEIVd
实际上不建议使用这个漏洞;如果X
是类类型的对象,那么X::i
和X.i
可能是完全不同的东西。
要从标准中得出这个结论,请从 3.4.3(限定查找,这是我们最终分析的高级结构(开始,在第 1 段中说,
类或命名空间成员或枚举器的名称可以在应用于表示其类、命名空间或枚举的嵌套名称说明符的 :: 范围解析运算符 (5.1( 之后引用。如果嵌套名称说明符中的 :: 范围解析运算符前面没有 decltype-说明符,则查找该 :: 前面的名称仅考虑专用化为类型的命名空间、类型和模板。如果找到的名称未指定命名空间或类、枚举或依赖类型,则程序格式不正确。
阅读第 2 段,它不适用,因为未声明限定 id。其余各段同样规定了不适用的例外情况。那么,::
之前的事情是什么?请参阅语法。
nested-name-specifier:
::
type-name ::
namespace-name ::
decltype-specifier ::
nested-name-specifier identifier ::
nested-name-specifier templateopt simple-template-id ::
只有type-name ::
和namespace-name ::
符合我们的先验标准。这些也与我们目前发现的重叠。在特定情况下,通常如何解决type-name
或namespace-name
?不合格的查找。继续执行 3.4.1。
首先,3.4.1/1 是要记住的一般规则:
在 3.4.1 中列出的所有情况下,将按照每个类别中列出的顺序搜索范围以查找声明;一旦找到名称的声明,名称查找就会结束。如果未找到声明,则程序格式不正确。
下一个适用的段落是6:
在函数的声明符 id 之后的函数定义中使用的名称,该函数是命名空间 N 的成员(其中,仅出于说明目的,N 可以表示全局范围(应在使用它的块或其封闭块之一中使用之前声明 (6.3( 或, 应在命名空间 N 中使用之前声明,或者,如果 N 是嵌套命名空间,则应在 N 的封闭命名空间之一中使用之前声明。
此规则并没有告诉我们实际在全局命名空间中搜索名称,但它确实在列表中提到了函数的封闭命名空间(在本例中为全局命名空间(,并且第 1 段说搜索列出的命名空间。因此,这足以构造名称查找。
令人惊讶的是,它没有提到递归搜索优先考虑内部封闭的命名空间,但您的示例中实际上没有这样的东西,所以我将在这里停止:)。将编译留给编译器要快得多,并且仅在出现问题时才手动工作。
在您给出的示例中,X
将被视为非限定名称查找。 因此,它确实遵循 3.4.1 中的规则
在这种情况下,搜索的命名空间如下所示:
- 定义之前的
main()
函数的本地命名空间。(其中不能根据 7.3.1.4 定义命名空间。 - 全局命名空间。
恐怕我无法指出标准中明确表示命名空间名称与任何其他名称相同的位置。 但他们是。 名称查找不知道这是一个命名空间名称(它可以是类名或结构名(,直到它实际找到具有该名称的命名空间。
- 在类设计中查找外部命名空间中的重载运算符
- 运算符<<依赖于参数的查找不在全局命名空间中查找
- 使用 dlsym 查找命名空间中符号的符号
- C++嵌套的"命名空间""使用"名称查找首选项顺序
- 范围运算符需要查找 std 命名空间而不是提升
- C++奇怪的命名空间查找行为
- 为什么在语句"std::cout << std::endl;"中使用时需要命名空间限定,给定依赖于参数的查找?
- C++如何知道在哪里查找使用 "using namespace ..." 指定的命名空间?
- 依赖于参数的查找在来自另一个命名空间的别名类型上意外行为
- 模板类继承命名空间的名称查找
- 依赖于参数的名称查找:添加要查找的额外命名空间
- 是否应该延迟类成员访问表达式中依赖类/命名空间名称的名称查找
- 在查找命名空间名称的过程中,可以考虑与命名空间名称不同的其他名称
- 强制名称查找以考虑命名空间范围
- 是否应该延迟类模板定义中由 this-> 限定的类/命名空间名称的名称查找?
- 嵌套名称说明符中第一个命名空间名称的名称查找
- 在查找期间在std命名空间中拖动外部命名空间
- c++,命名空间,对继承类和Qt的名称查找
- 非限定名称查找查找内联命名空间成员
- 顶级命名空间中类的参数依赖查找