3

There is a simple code with the different aspects of usage of :: operation.

namespace test{
    int add(int x, int y){
          return x + y;
    }
}


int main(){
    int x=3, y=5;
    int r = ::test::add(x,y);
    r = test::add(x,y);
}

or in another example

::std::cout << "Hello";
std::cout << "Hello";

The functionality of these codes (I mean the usage of :: before statement) is not different. Then why is it (::) used before statements?

kaylum
  • 13,833
  • 2
  • 22
  • 31
mo bejani
  • 33
  • 4
  • The difference is in the name lookup, ::std forces to look in the root namespace std. just using std can end up in a local subnamespace e.g. my_own_namespace::std. When I write libraries I often explicitly navigate to the required full namespace from root (so start with ::) to avoid nameclashes with code that uses my library. So I imagine you won't see the difference, that usually only happens in larger projects. – Pepijn Kramer Jun 05 '22 at 11:30
  • `::std::cout` is useful only if you add a different `std::cout` in an inner namespace, and then find out that you *still* have to use the outer one. Just don't put yourself in that position! *"Doctor, doctor, it hurts when I do this!"* – BoP Jun 05 '22 at 12:05

1 Answers1

2

The difference is that one is a fully qualified name, and the other is not a fully qualified name. Whether the fully qualified name is used or not doesn't make a practical difference in these examples. It could make a difference in another context. See the further down for an example.

To understand the concept it may help if you are familiar with other cases of qualified names.

Consider for example the UNIX/LINUX filesystem. The path separator is / in contrast to C++ namespaces whose separator is ::. The root of the filesystem is / while the global namesoace is ::. At the root is a file named foo. Current working directory is the root. What is the difference between the paths /foo and foo? They both refer to the same file, but the first is an absolute (i.e. fully qualified) while the other is relative (unqualified). Now consider changing working directory to /bar. In this context, the relative path now refers to /bar/foo and no longer refers to the same file as /foo.

Another, similar analogy is the web. Let's say you are on page bar.org. What is the difference between urls http://bar.org/foo, bar.org/foo, //foo, /foo, and foo? They all refer to the same entity. The first is fully qualified, the last is unqualified, and the others have various levels of qualification. If you browse to bar.org/baz or perhaps zap.org, the relative URL change meaning while the absolute do not.

C++ name lookup is more complex than these analogous examples in that it can match relative names to parent namespaces of the active namespace while filesystem paths and URLs generally don't. This difference has no effect in your example cases.

A simple example here qualification of a name does make a difference:

int foo = 1;

namespace bar {

int foo = 2;

void baz() {
    std::cout << foo;
    std::cout << ::foo;
}

}
eerorika
  • 232,697
  • 12
  • 197
  • 326