Name lookup works in terms of names. The name is looked up, independent of what that name designates.
It's not permitted for the same name to be declared as both a function and a variable, in the same scope.
However, it is permitted for class X
to exist even if X
is the name of a function or a variable. When you have class X
, then the current scope gets X
as a name (designating that class). If the same scope has X
declared as both a typename and a variable name, then just looking up x
finds the variable name.
If a new scope declares X
then any use of X
in that scope finds the name declared in its scope, this is called shadowing. (Name lookup searches the current scope, then the scope which enclosed that, and so on up to the global scope).
Error, attempts to declare main
as both a function and a variable
To process main obj;
, the name main
is looked up. The current scope is checked first, and it finds the function name main
; so it does not check the global scope. We say that the inner scope's name shadows the outer scope's name. So, it is the same error as you would get from void foo(); foo obj;
class main
unambiguously says to look up the class name main
; that does not find int main()
so it falls back to checking the global scope.
nothing new, main obj;
makes no difference .
Another interesting example would be:
int x;
class x { };
int main()
{
x = 1; // ok
x y; // error, `x` means the int
class x y; // ok
}