::std::cout与std::cout有何不同?

3

这里有一个简单的代码,涵盖了::操作符的不同用法。

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);
}

或者换句话说

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

这些代码的功能(我指语句前面使用::)并没有不同。那么为什么要在语句前使用 ::

区别在于名称查找,::std 强制查找根命名空间 std。仅使用 std 可能会在本地子命名空间中结束,例如 my_own_namespace::std。当我编写库时,我经常明确导航到所需的完整命名空间,从根开始(因此以 :: 开头),以避免与使用我的库的代码发生名称冲突。因此,我想象您不会看到区别,这通常只发生在较大的项目中。 - Pepijn Kramer
只有在添加内部命名空间中的不同 std::cout 并发现您仍然需要使用外部命名空间时,::std::cout 才有用。不要让自己陷入这种境地!“医生,医生,我这样做会疼!” - BoP
1个回答

2
区别在于一个是完全限定名称,而另一个不是。在这些例子中使用完全限定名称与否并没有实际上的区别。但在其他情况下可能会有所不同。请参见下面的示例。
为了理解这个概念,如果您熟悉其他限定名称的情况可能会有所帮助。
例如,考虑UNIX/LINUX文件系统。路径分隔符是/,而C++命名空间的分隔符是::。文件系统的根目录是/,而全局命名空间是::。在根目录下有一个名为foo的文件。当前工作目录是根目录。/foo和foo之间有什么区别?它们都指向同一个文件,但前者是绝对(即完全限定)路径,而后者是相对(未限定)路径。现在考虑将工作目录更改为/bar。在这种情况下,相对路径现在指的是/bar/foo,不再指向与/foo相同的文件。
另一个类似的比喻是网络。假设您在页面bar.org上。urls http://bar.org/foo, bar.org/foo, //foo, /foo和foo之间有什么区别?它们都指的是同一实体。第一个是完全限定的,最后一个是未限定的,其他的有各种不同级别的限定。如果您浏览到bar.org/baz或zap.org,相对URL会改变含义,而绝对URL则不会。
C++名称查找比这些类似的例子更复杂,因为它可以将相对名称与活动命名空间的父命名空间匹配,而文件系统路径和URL通常不能。这种差异在您的示例情况下没有影响。
在这里,名称的限定确实有所不同的一个简单的例子:
int foo = 1;

namespace bar {

int foo = 2;

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

}

你能提供你所提到的上下文吗? - mo bejani
@mobejani 我已经添加了一个例子。 - eerorika
@eerorika 非常感谢。我测试了这个例子,现在完全明白了。 - mo bejani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接