我在代码中看到了这两种方法。你能解释一下它们之间的区别吗?我认为这与C++的命名空间查找方式有关,你能提供一些相关信息或者好的文档链接吗?谢谢。
示例:
#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;
}
输出:
x::i = 2 ::x::i = 1
解释:
当你引用诸如 x::i
这样的标识符时,使用的定义是最“近”的 x::i
。在 ::y::func
中,定义 ::y::x::i
比定义 ::x::i
更接近。相反地,没有这样的函数 ::y::std::printf
,所以使用了 ::std::printf
。
当你引用诸如 ::x::i
这样的标识符时,不存在任何可能的歧义:它查找名为 x
的顶层命名空间,然后找到其中一个 i
。
因此,使用开头的 ::
允许你拼写全局对象的完整名称,并且可以区分局部变量和全局变量。
示例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;
}
输出:
x = 7 ::x = 5
std
不存在于y
中,因此编译器会检查全局命名空间并在其中找到它。 - Ken Wayne VanderLinde大部分时间来说,这并不重要。
在格式为::identifier1::identifier2
的情况下,前面的冒号表示在全局范围内查找identifier1
,然后在该范围内查找identifier2
。
在格式为identifier1::identifier2
的情况下,我们会在当前范围内查找identifier1
。如果没有找到,则会搜索父范围,直到找到为止。然后,在刚刚找到的任何范围内搜索identifier2
。
如果你已经处于全局范围内,那么这并不重要。但是,在工作中使用命名空间或嵌套其他命名空间或类的类时,情况就会发生改变。
/usr/bin/rm
和usr/bin/rm
之间的区别,或者是Windows\calc.exe
和C:\Windows\calc.exe
之间的区别。 - Kerrek SB