嵌套if中的范围歧义

时间:2012-02-15 21:23:03

标签: c++ scope

假设有一个类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块的末尾?

3 个答案:

答案 0 :(得分:7)

C ++很高兴您声明一个具有相同名称的变量,只要它在嵌套范围内,这样就没有歧义。

  

我希望foo.bar()在第二个foo上执行(它的范围是“更接近”)

你是对的

  

但我保证它实际上是与第一个foo不同的对象吗?

  

此外,他们是否各自独立处置(他们的析构函数被称为)在各自的if块的末尾?

答案 1 :(得分:4)

  

我希望foo.bar()在第二个foo上执行(它的范围是“更接近”)

正确。

  

但我保证它实际上是与第一个foo不同的对象吗?

  

此外,他们是否各自独立处置(他们的析构函数被称为)在各自的if块的末尾?

是的,你已经得到了它。

答案 2 :(得分:2)

在您的示例中使用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