Let's say one has a class Foo such as
class Foo {
public:
void bar();
operator bool() const { return true; }
};
then one can do
if(Foo foo = Foo())
{
if(Foo foo = Foo())
{
foo.bar();
}
}
Now I'm having trouble grasping the scope resolution going on here (I would've expected a compiler error for redeclaring foo).
I expect foo.bar() to execute on the second foo (its scope is "closer") but am I garanteed that it's actually a different object than the first foo? Furthermore, are they each independently disposed (their destructor called) at the end of their respective if blocks?
C++ is quite happy for you to declare a variable with the same name, as long as it is inside a nested scope so there is no ambiguity.
I expect foo.bar() to execute on the second foo (its scope is "closer")
You are correct
but am I garanteed that it's actually a different object than the first foo?
Yes
Furthermore, are they each independently disposed (their destructor called) at the end of their respective if blocks?
Yes
I expect foo.bar() to execute on the second foo (its scope is "closer")
Correct.
but am I garanteed that it's actually a different object than the first foo?
Yes.
Furthermore, are they each independently disposed (their destructor called) at the end of their respective if blocks?
Yes, you've got it.
The use of if statements and class object initialization in your example tends to obscure the relevant point, which is that declarations in inner scopes are perfectly legal and hide declarations of the same name in outer scopes.
A perhaps clearer example:
#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";
}
The output is:
outer x is 10
inner x is 12.34 (it hides the outer x)
outer x is still 10 (inner x no longer exists)
Note that the inner and outer x
s aren't even of the same type.
Though this is legal, it's usually not a good idea; the compiler has no problem with it, but it can be confusing to human readers. If you compile with g++ -Wshadow
, you'll get warnings:
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