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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With