Search code examples
c++operatorslanguage-designscope-resolution

Why does C++ need the scope resolution operator?


(I know what the scope resolution operator does, and how and when to use it.)

Why does C++ have the :: operator, instead of using the . operator for this purpose? Java doesn't have a separate operator, and works fine. Is there some difference between C++ and Java that means C++ requires a separate operator in order to be parsable?

My only guess is that :: is needed for precedence reasons, but I can't think why it needs to have higher precedence than, say, .. The only situation I can think it would is so that something like

a.b::c;

would be parsed as

a.(b::c);

, but I can't think of any situation in which syntax like this would be legal anyway.

Maybe it's just a case of "they do different things, so they might as well look different". But that doesn't explain why :: has higher precedence than ..


Solution

  • Why C++ doesn't use . where it uses ::, is because this is how the language is defined. One plausible reason could be, to refer to the global namespace using the syntax ::a as shown below:

    int a = 10;
    namespace M
    {
        int a = 20;
        namespace N
        {
               int a = 30;
               void f()
               {
                  int x = a; //a refers to the name inside N, same as M::N::a
                  int y = M::a; //M::a refers to the name inside M
                  int z = ::a; //::a refers to the name in the global namespace
    
                  std::cout<< x <<","<< y <<","<< z <<std::endl; //30,20,10
               }
        }
    }
    

    Online Demo

    I don't know how Java solves this. I don't even know if in Java there is global namespace. In C#, you refer to global name using the syntax global::a, which means even C# has :: operator.


    but I can't think of any situation in which syntax like this would be legal anyway.

    Who said syntax like a.b::c is not legal?

    Consider these classes:

    struct A
    {
        void f() { std::cout << "A::f()" << std::endl; }
    };
    
    struct B : A
    {
        void f(int) { std::cout << "B::f(int)" << std::endl; }
    };
    

    Now see this (ideone):

    B b;
    b.f(10); //ok
    b.f();   //error - as the function is hidden
    

    b.f() cannot be called like that, as the function is hidden, and the GCC gives this error message:

    error: no matching function for call to ‘B::f()’
    

    In order to call b.f() (or rather A::f()), you need scope resolution operator:

    b.A::f(); //ok - explicitly selecting the hidden function using scope resolution
    

    Demo at ideone