Home > Mobile >  What is the point of the scope resolution operators?
What is the point of the scope resolution operators?

Time:10-30

A question dawned on me lately: Why bother having the scope resolution operator (::) when the usage of the dot operator (.) doesn't clash with the former?

Like,

namespace my_module
{
    const int insane_constant = 69;
    int some_threshold = 100;
}

In order to access some_threshold, one would write my_module::some_threshold. But the thing is the left hand side of :: must be a namespace or a class, as far as I know, while that of the . can never be a namespace or a class. Moreover, the order of :: is higher than ., which is really pointless in my opinion. Why make 2 distinct operators, both of which cannot be overloaded, with use cases can be covered with just one? I'm having a hard time finding any satisfying answer, so any clue on this matter is much appriciated.

CodePudding user response:

Consider the following code:

#include <iostream>
namespace my_module
{
    const int insane_constant = 69;
}
class C{
    public:
    int insane_constant; // actually not constant, but for the example's sake
};
int main(){
  C my_module;
  my_module.insane_constant = my_module::insane_constant;
  std::cout << my_module.insane_constant;
}

How would you distinguish my_module. from my_module:: here?

CodePudding user response:

You can't replace one with the other.
Example:

namespace A
{
    int x = 0;
    struct X { int x = 1; } A;
    void f()
    {
        std::cout << A.x
                  << A::x
                  << std::endl;
    }
}


int main()
{
    A::f();
}

prints "10".

CodePudding user response:

Both operators have completely different purposes.

In particular, :: is for referring to a member of a scope while operator. is for referring to a member of an object.

That is, operator:: works on scope while operator. works on objects.

For instance, a classname::membername refers to the member of a class which has a class scope associated with it. On the other hand, object.membername refers to the member of the object object.

Note that not all scopes can be used with operator::. For example, we can refer to a namespace scope's member, class scopes' member(like a static member etc), enumeration' member etc using operator::.

CodePudding user response:

The other answers showcase situations where :: and . do different things because they act on different entities (scopes vs objects). I'd like to add a bit of motivation behind this choice in the language by comparing it with the situation in C#. Disclaimer: I don't actually use C#, but these points seem obvious when looking into it.

In C#, the "namespace operator" is a dot ., just like the member access operator. However, you cannot have truly global variables: you need a class to put them in. In fact, you cannot even declare a class without a namespace, though this is unrelated to your question.

In C#, there is no possible ambiguity when using the dot between scope and object. Nested namespaces, classes within namespaces, class static variables, enumerators, and so on, are all accessed with a dot.

In C , that's obviously not the case, and the language took the route of distinguishing between scopes and objects by having two distinct operators.

In plain C, there is no scope resolution, so there is no need for a :: operator. Other languages that make the distinction are Ruby and, apparently, PHP. Among languages that do not make the distinction, you can find for example Python, Go and Java. That last one does have a :: operator, but it's not for scope resolution, it's for forming method references.

In short, C has complex scope mechanisms because that's how the language was designed. As a result, it requires two different operators to distinguish scope access and object access.

  • Related