名称查找规则在哪里定义,可以找到最直接的名称声明?

时间:2018-07-28 19:22:09

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

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]中的其他所有段落均不适用于非成员函数。所以我的问题是该标准在哪里指定?

1 个答案:

答案 0 :(得分:4)

[basic.scope.declarative]中,我们有:

  
      
  1. 每个名称都会在程序文本的称为“ 声明性区域”的部分中引入,这是该名称在其中有效的最大部分,即该名称在其中可以用作引用同一实体的不合格名称。   通常,每个特定名称仅在程序文本的某些可能不连续的部分(称为 scope )中有效。   要确定声明的范围,有时可以方便地引用声明的潜在范围。   声明的范围与其潜在范围相同,除非潜在范围包含另一个同名声明。   在那种情况下,内部(包含)声明性区域中声明的潜在范围被排除在外部(包含)声明性区域中声明的范围

  2.   
  3. [示例:

    // globals are bad, I know
    should_blink = true
    
    // right before Ajax call
    should_blink('#my-button', do_animate);
    
    
    // inside Ajax call success
    do_animate = false;
    should_blink('#my-button', do_animate);
    
    function should_blink(selector, do_animate) {
        console.log(do_animate);
        if (do_animate) {
        $(selector).fadeOut(300, function () {
            $(this).fadeIn(300, function () {
                should_blink(this, do_animate);
                })})}
                else {
                    $(this).fadeIn(300);
                }
            }
    
         

    标识符date_seq <- as.character(seq(as.Date("2017-07-01"), as.Date("2017-07-30"), by = "day")) for (i in 1:length(date_seq)) { string <- "select X, Y, z from table where date between date'REPLACEME' - interval '31' day and date'REPLACEME' - interval '1' day" string <- gsub("REPLACEME", date_seq[i], string) print(string) # replace this with the dbSendQuery } [1] "select X, Y, z from table where date between date'2017-07-01' - interval '31' day and date'2017-07-01' - interval '1' day" [1] "select X, Y, z from table where date between date'2017-07-02' - interval '31' day and date'2017-07-02' - interval '1' day" ... [1] "select X, Y, z from table where date between date'2017-07-30' - interval '31' day and date'2017-07-30' - interval '1' day" 被两次声明为名称(并被使用两次)。   第一个int j = 24; int main() { int i = j, j; j = 42; } 的声明性区域包括整个示例。   第一个j的潜在范围从该j之后立即开始,一直延伸到程序的末尾,但其(实际)范围排除了j和{{1 }}。   j的第二个声明的声明性区域(分号前的,)包括}j之间的所有文本,但其潜在范围不包括j。   {的第二个声明的范围与其潜在范围相同。   — 示例]

  4.   

(强调我的。)

在您的

}

例如,i必须引用本地j,因为全局int a = i; 的范围实际上不在这里。

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

  

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

但是,如果只在一个范围内声明一个声明,我们选择哪种搜索顺序都没关系。