提问者:小点点

为什么“使用名称空间std;”被认为是糟糕的做法?


其他人告诉我,在代码中使用名称空间std;编写是错误的,我应该直接使用std::coutstd::cin

为什么使用namespace std;被认为是一种糟糕的做法?它是否效率低下,或者有可能声明不明确的变量(与std命名空间中的函数共享相同名称的变量)?是否影响性能?


共2个答案

匿名用户

这与性能根本没有关系。但请考虑以下内容:您使用了两个名为Foo和bar的库:

using namespace foo;
using namespace bar;

一切正常,您可以从Foo调用blah()和从Bar调用quux()而不会出现问题。但有一天您升级到Foo2.0的新版本,该版本现在提供了一个名为quux()的函数。现在有一个冲突:Foo 2.0和Bar都将quux()导入到全局名称空间中。这将需要一些努力来修复,特别是当函数参数碰巧匹配时。

如果您使用了foo::blah()bar::quux(),那么foo::quux()的引入将是一个非事件。

匿名用户

我同意格雷格所写的一切,但我想补充一点:它甚至会变得比格雷格说的更糟!

Library Foo 2.0可以引入一个函数quux(),与您多年来调用的bar::quux()相比,这个函数更适合您对quux()的一些调用。那么您的代码仍然在编译,但是它静默地调用了错误的函数,并且做了天晓得的事情。事情已经糟透了。

请记住,std命名空间有大量标识符,其中许多是非常常见的标识符(例如listsortstringiterator等),它们也很可能出现在其他代码中。

如果您认为这是不可能的:这里有一个关于堆栈溢出的问题,在我给出这个答案大约半年后,几乎完全发生了这种情况(由于省略了std::前缀而调用了错误的函数)。这是另一个关于这类问题的更近期的例子。所以这是一个真正的问题。

这里还有一个数据点:很多很多年以前,我还经常发现必须在标准库中的所有内容前缀std::很烦人。然后我在一个项目中工作,一开始就决定禁止使用指令和声明,但函数范围除外。猜猜看?我们大多数人花了几个星期的时间来习惯写前缀,几个星期后,我们大多数人甚至同意它实际上使代码更易读。这是有原因的:你喜欢短的还是长的散文是主观的,但前缀客观上增加了代码的清晰度。不仅是编译器,您也会发现更容易看到引用了哪个标识符。

在十年的时间里,这个项目发展到拥有几百万行代码。由于这些讨论一次又一次地出现,我曾经很好奇(允许的)函数范围using在项目中实际使用的频率是多少。我查了它的来源,只找到一二十个地方使用它。对我来说,这表明,一旦尝试过,开发人员就不会发现std::有足够的痛苦来使用using指令,即使在允许使用的地方也是如此,即使是每100 kLoC使用一次。

底线:明确地给每件事加上前缀不会有任何坏处,很少需要习惯,而且有客观的优势。特别是,它使编译器和人类读者更容易解释代码--这也许应该是编写代码时的主要目标。