【问题标题】:Where is name lookup rule defined that finds the most immediate declaration of a name?查找名称的最直接声明的名称查找规则在哪里定义?
【发布时间】:2018-07-28 19:22:09
【问题描述】:
int i;
void f()
{
    int i{};
    {
        int a = i; // local or global 'i'?
    }
}

我的问题不是选择哪个i,因为很明显它是本地的,而是指定的标准中的哪个位置。

我能找到的最接近的规则是[basic.lookup.unqual]p6,上面写着:

在作为命名空间 N 成员的函数的定义中,在函数的 declarator-id 之后使用的名称应在使用它的块中或在一个块中使用之前声明它的封闭块 ([stmt.block]) 或应在其在命名空间 N 中使用之前声明,或者,如果 N 是嵌套命名空间,则应在其在 N 的封闭命名空间之一中使用之前声明。

但它只是说必须在使用前的某个时间声明名称;这不是我要找的。同一段中的示例使一切都更加清晰,因为它说明了按什么顺序搜索了哪些范围,但它是一个示例,因此不是主格的。

[basic.lookup.unqual] 中的所有其他段落都不适用于非成员函数。所以我的问题是这个标准在哪里指定?

【问题讨论】:

  • @melpomene 这只是描述了实体的范围,而不是名称查找 IIUC 的工作原理。
  • 是的,但是名称查找 looks in scopes,在您的示例中,全局 i 不在范围内(根据我的其他链接)。
  • @melpomene 哦哦哦我明白了。我误读了那部分。现在它是有道理的...... :)(可能想写一个答案顺便说一句)

标签: c++ scope language-lawyer name-lookup


【解决方案1】:

在[basic.scope.declarative] 我们有:

  1. 每个名称都被引入程序文本的某个部分,称为 声明性区域,这是程序中该名称有效的最大部分,也就是说,该名称在其中可以用作非限定名称来指代同一实体。 通常,每个特定名称仅在程序文本的某个可能不连续的部分(称为其范围)内有效。 为了确定声明的范围,有时参考声明的潜在范围会很方便。 声明的范围与其潜在范围相同,除非潜在范围包含另一个同名声明。 在这种情况下,内部(包含)声明性区域中的声明的潜在范围被排除在外部(包含)声明性区域中的声明范围之外。

  2. [ 例子:在

    int j = 24;
    int main() {
      int i = j, j;
      j = 42;
    }
    

    标识符j 被声明为名称两次(并使用了两次)。 第一个j 的声明区域包括整个示例。 第一个j 的潜在范围紧随j 之后开始并延伸到程序的末尾,但它的(实际)范围不包括, 和} 之间的文本。 j 的第二个声明的声明区域(分号之前的 j)包括 { 和 } 之间的所有文本,但它的潜在范围不包括 i 的声明。 j 的第二个声明的范围与它的潜在范围相同。 — 结束示例 ]

(强调我的。)

在你的

int a = i;

例如,i 必须引用本地 i,因为全局 i 实际上不在此处的范围内。

正如[basic.lookup.unqual]开头所说:

在 [basic.lookup.unqual] 中列出的所有情况下,将按照每个相应类别中列出的顺序搜索范围以查找声明 [...]

但如果一开始只有一个声明在范围内,我们选择哪种搜索顺序并不重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多