嵌套if中的作用域不明确

Scope ambiguity in nested if

本文关键字:作用域 不明确 if 嵌套      更新时间:2023-10-16

假设有一个类Foo,如

class Foo {
public:
  void bar();
  operator bool() const { return true; }
};

那么就可以进行

if(Foo foo = Foo())
{
  if(Foo foo = Foo())
  {
    foo.bar();
  }
}

现在我很难理解这里正在进行的范围解析(我本以为重新解析foo会出现编译器错误)。

我希望foo.bar()在第二个foo上执行(它的作用域"更近"),但我是否确信它实际上是一个与第一个foo不同的对象?此外,它们是否在各自if块的末尾分别独立处理(称为析构函数)?

C++非常乐意用相同的名称声明一个变量,只要它在嵌套的范围内,就不会有歧义。

我希望foo.bar()在第二个foo上执行(它的作用域"更近")

你是正确的

但我是否确信它实际上是一个与第一个foo不同的对象?

此外,它们是否在各自if块的末尾分别独立处理(称为析构函数)?

我希望foo.bar()在第二个foo上执行(它的作用域"更近")

正确。

但我是否确信它实际上是一个与第一个foo不同的对象?

是的。

此外,它们是否在各自if块的末尾分别独立处理(称为析构函数)?

是的,你找到了。

在示例中使用if语句和类对象初始化往往会混淆相关点,即内部作用域中的声明完全合法,并在外部作用域中隐藏同名声明。

一个可能更清晰的例子:

#include <iostream>
int main() {
    const int x = 10;
    std::cout << "outer x is " << x << "n";
    {
        const double x = 12.34;
        std::cout << "    inner x is " << x << " (it hides the outer x)n";
    }
    std::cout << "outer x is still " << x << " (inner x no longer exists)n";
}

输出为:

outer x is 10
    inner x is 12.34 (it hides the outer x)
outer x is still 10 (inner x no longer exists)

请注意,内部和外部x甚至不属于同一类型。

虽然这是合法的,但通常不是一个好主意;编译器对它没有问题,但它可能会让人类读者感到困惑。如果使用g++ -Wshadow进行编译,则会收到警告:

c.cpp: In function ‘int main()’:
c.cpp:6:22: warning: declaration of ‘x’ shadows a previous local
c.cpp:3:15: warning: shadowed declaration is here