Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between writing "::namespace::identifier" and "namespace::identifier"?

I have seen both approaches in code. Could you explain what's the difference between the two? As I think it relates to the way namespace lookup is done by C++, could you provide some information on this as well, or perhaps a link to a good doc? Thanks.

like image 241
Dan Nestor Avatar asked Dec 03 '22 06:12

Dan Nestor


2 Answers

Example:

#include <cstdio>

namespace x {
    const int i = 1;
}

namespace y {
    namespace x {
        const int i = 2;
    }

    void func()
    {
        std::printf("x::i = %d\n", x::i);
        std::printf("::x::i = %d\n", ::x::i);
    }
}

int main()
{
    y::func();
    return 0;
}

Output:

x::i = 2
::x::i = 1

Explanation:

  • When you refer to an identifier like x::i, the definition used is the "closest" x::i. Inside ::y::func, the definition ::y::x::i is closer than the definition ::x::i. By contrast, there is no such function ::y::std::printf so ::std::printf is used instead.

  • When you refer to an identifier like ::x::i, there is no possible ambiguity: it looks for a top-level namespace named x, then finds an i inside.

So using :: at the beginning allows you to spell the full name of a global something. This also allows you to distinguish between local and global variables.

Example 2:

#include <cstdio>
const int x = 5;
int main()
{
    const int x = 7;
    std::printf("x = %d\n", x);
    std::printf("::x = %d\n", ::x);
    return 0;
}

Output:

x = 7
::x = 5
like image 66
Dietrich Epp Avatar answered Dec 05 '22 21:12

Dietrich Epp


It doesn't really matter, at least not most of the time.

In the format ::identifier1::identifier2, the preceding colon says to look at global scope for identifier1, and then look for identifier2 in that scope.

In the format identifier1::identifier2, we instead look at the current scope for identifier1. If we don't find it, then the parent scope is searched, and so on until we find it. We then search for identifier2 within whatever scope we just found.

In the case where you're already at global scope, it won't matter. But that story changes when you're working within a namespace or classes that has other namespaces or classes nested within it.

like image 33
Ken Wayne VanderLinde Avatar answered Dec 05 '22 20:12

Ken Wayne VanderLinde