Search code examples
c++classintegerlanguage-lawyeroverloading

Overloading class name with integer variable


I am learning C++ using the books listed here. In particular, i read about overloading. So after reading i am trying out different examples to clear my concept further. One such example whose output i am unable to understand is given below:

int Name = 0;

class Name 
{
    int x[2];  
};
void func()
{
    std::cout << sizeof(Name) << std::endl; //My question is: Why here Name refers to the integer variable Name and not class named Name
}

int main()
{
    func();
    
}

When i call func, then in the statement std::cout << sizeof(Name) << std::endl;, Name refers to the int Name and not class named Name. Why is this so? I expected that this would give me ambiguity error because there are two(different) entities with the same name. But the program works without any error and sizeof is applied to int Name instead of class named Name. I have read about function overloading in the books. But not about this kind of overloading. What is it called and what is happening here.

PS: I know that i can write std::cout<< sizeof(class Name); where sizeof will applied to the class named Name instead of variable int Name. Also, the example is for academic purposes. I know that use of global variable should be avoided. The question is not about how to solve this(say by not using same name for those two entities) but about what is happening.


Solution

  • When a class and a variable of the same name are declared in the same scope, then the variable name hides the class name whenever name lookup would find both of them. Looking at [basic.scope.hiding]/21 of the post-C++20 standard draft:

    If a class name ([class.name]) or enumeration name ([dcl.enum]) and a variable, data member, function, or enumerator are declared in the same declarative region (in any order) with the same name (excluding declarations made visible via using-directives ([basic.lookup.unqual])), the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.

    I think this behavior, instead of making it an error to declare both a class and a variable of the same name in the same scope, was chosen for compatibility with C. In C the names of structs are in a separate namespace from variable names, so they are never ambiguous. For example with

    int Name = 0;
    
    struct Name 
    {
        int x[2];  
    };
    

    in C, whenever you write just Name it refers to the variable. If you want to refer to the type you must use struct Name. C++ eliminates the requirement to use the struct prefix to refer to unambiguous structs, but with the rules as they are, name lookup for both Name and struct Name will have the same results in C and C++.

    1: Note that there was significant rework of the wording for name lookup in the current standard draft for C++23, but it should have the same effect