我听说人在众多 occasions,我的老师建议的 【using namespace std代码中的错误。因此,我们应该使用std::coutstd::cin.

为什么是using namespace std认为是不正确的做法吗?真的,效率低下或风险声明明确变量 ( std命名空间中的函数同名的变量)?或者,此影响性能?

2009-09-21 03:08:23
问题评论:

Google 的 c + + 风格指南真的不能回答您的问题,但有大量常规"原因"s: google-styleguide.googlecode.com/svn/trunk/...

别忘了要做到:"使用 std::cout;"这意味着您不必键入 std::cout,但在同时,整个标准命名空间不带。

如何将工作的 @Bill 吗?<< "Hello, World!";: P

@muntoo Heh。开个玩笑了,但是只是以防万一,他意味着您可以键入 cout 而不是键入 std::cout。

听起来更象一个 Valgrind 错误,为"使用命名空间"这一不起...

回答:

这不相关性能的根本。但考虑这个问题︰ 使用的两个名为 Foo 和栏的库︰

using namespace foo;
using namespace bar;

一切都工作正常,您可以从 Foo 和Quux()从调用Blah()条没有问题。但是一天您升级到新版本的 Foo 2.0,现在提供了调用Quux()函数。现在你有冲突︰ 既 Foo 2.0 和栏将Quux()导入您的全局命名空间。这将需要一些努力来解决问题,尤其是碰巧匹配的函数参数。

如果您已使用foo::Blah()bar::Quux(),然后引入了foo::Quux()就已非事件。

我一直很喜欢 Python 的"导入为 bhn big_honkin_name"以便您可以只使用"bhn.something"而不是"big_honkin_name.something"-实际上可以减少键入。C + + 没有事情吧?

@Pax 命名空间 io = boost::filesystem;

我认为它过分夸大事情说的"一些努力来解决"。您必须这样只是消除歧义与 bar::Quux 的所有您当前使用的新 foo::Quux 没有实例。

将任何明智的人创建库类型其不合格的名称发生冲突的标准类型?

@TomA: 问题#define是它不会限制自己的命名空间,但对整个代码库 tramples。命名空间别名是您所需的信息。

我同意一切Greg 写了,但我想要添加︰甚至可以获得比 Greg 说更糟 !

库 Foo 2.0 可以引入一个函数Quux(),调用Quux()bar::Quux()年来调用您的代码的某些明确更好的匹配然后您仍将编译代码,但它以无提示方式调用错误的函数但不上帝-知道的模拟。这就是关于像糟糕事情可能会变。

请记住std命名空间已吨的标识符,其中许多是常见的 (思考listsortstringiterator等) 是非常有可能出现在其他代码中,太。

如果您认为这不太可能发生︰没有问的问题这里堆栈溢出这几乎正好发生在 (错误的函数调用由于省略std::前缀) 大约半年后我给此答案。这里是另一种较新的此类问题的示例这是一个真正的问题.


下面是一个更多的数据点︰ 许多、 许多年以前,我还用来发现很令人讨厌的无需一切都与标准库中的前缀std::然后我从事其中时间决定开始using指令和声明都禁止除函数作用域之外的项目。您猜怎么样?它需要我们大多数人很少几个星期以获取对用于编写该前缀,并在几个星期后我们大多数人甚至达成协议,使其成为真正的代码更具可读性(还有一个理由︰是否要更短或更长时间枯燥文字活泼起来是主观的但前缀客观地对代码更加明晰。 不仅编译器,但是,也发现更容易看到哪个标识符引用的。)

在十年中,该项目发展多个几百万行的代码。由于这些讨论一次又一次提出,我一次是好奇频率 (允许) 函数作用域using实际的项目中使用。我 grep 有它的来源和只能找到使用它的一个或两个十几个位置。这在向我表明,开发人员尝试,一旦找不到std::足够困难使用 using 指令甚至一次每个 100 kLoC甚至在其中它被允许使用.


底线︰ 明确作为前缀的所有内容不做任何损害,习惯,没有采用几乎获取或具有客观的优点。特别是,它使代码容易解释由编译器和人类读者 — — 并且,可能应该是主要目标,在编写代码时。

它大大 does 危害的代码可以打包在单个行中的密度。最终在非常长的方法; 编写代码这减少了可读性。就个人而言,我认为较短 (但不是太短) 的代码往往更具可读性 (因为没有更少的东西来阅读和更少的东西以有关分散注意力)。

猜猜之前 c + + 标准string类,并且似乎是每个库都有他们自己的旧日子错过了。告诉您的是︰ 我们将保持我们的代码与编写std::,您可以通过运行我们的代码和grep -v std:: | vim当您在浏览。您可以教您的编辑器,或者std::是即是彩色背景色相同的关键字。任何工作。

我并不认为std::根本是有害。它携带非常重要的信息 (即"无论出现之后是标准库的一部分",并且它仍然是非常简单和简洁的前缀。大多数情况下,它根本没有问题。有时,您有几行代码需要用来指std命名空间很多中的特定符号,然后using语句,特定的范围可以很好地解决了问题。但一般情况下,它不是噪音,它传达有价值的信息除了删除含糊之处。

每当我看到std::,我知道它将从std::而无需考虑它。是否我看到本身stringlistmap,有点奇怪。

@LieRyan 然后编写几何库而不是以往任何时候都祝你好运命名一些vectortransformdistance和那些只是使用标准库中的许多许多常用名称的示例。不建议使用这些恐惧或命名空间功能的 c + + 的一个有机组成部分的偏置的意见是相反文职。

我认为这是不正确,将其放在您的类的头文件︰ 因为您将强制任何人使用您的类 (包括头文件),然后也使用 (即看到中的所有内容项) 其他这些命名空间。

但是,您可能会感到自由地使用 (专用) 的 *.cpp 文件中的语句。


请注意有些人反对与"随意"像这样-我说,因为尽管使用 cpp 文件中的语句更好于标头中 (因为它不影响包含头文件的人),他们认为仍不是很好(因为取决于代码它无法使更难维护类的实现)。本常见问题解答主题说,

Using 指令存在传统的 c + + 代码,并简化转换为命名空间,但是您可能不应该使用它定期,至少不在您的新 c + + 代码。

它提出两个备选方案︰

  • A 使用声明︰

    using std::cout; // a using-declaration lets you use cout without qualification
    cout << "Values:";
    
  • 获取在其上,只需键入 std::

    std::cout << "Values:";
    

不太坏,将比的.cpp 文件中某个标题,但相同的可维护性问题。它采用具有相同名称的两个函数将产生冲突时的风险代码/使用库/c + + 标准被修改。

是否尝试了这根本?因为 using 命名空间指令将不会延续到另一个文件。(GCC 4.8 +)

@zackery.fix,"苹果 LLVM (clang 700.1.81) 7.0.2 版"传播using namespace std;从页眉到源代码文件中,我验证和 GCC 却没有。这样,至少让标头中的"使用"的指令是危险的。

是的。。我不使用 LLVM 或 clang,这不是一种标准的方法继续。

实际上您应该不告诉人们"随意"使用命名空间在.cpp 文件中的标准。@Étienne 是合适的。

我最近遇到了有关Visual Studio 2010的投诉。事实证明,几乎所有的源代码文件有以下两行︰

using namespace std;
using namespace boost;

到 C + + 0x 标准,将大量的增强功能,Visual Studio 2010 突然不编译这些程序已有足够的 C + + 0x 功能。

因此,避免using namespace X;是一种未来校对,确保更改到的库和/或头文件中使用的一种方式都不会中断程序。

这。提升和标准有很多重叠-尤其是因为 C + + 11。

人不应该使用在全局范围内,尤其是在标题中使用指令。但是有的情况适当甚至在头文件中︰

template <typename FloatType> inline
FloatType compute_something(FloatType x)
{
    using namespace std; //no problem since scope is limited
    return exp(x) * (sin(x) - cos(x * 2) + sin(x * 3) - cos(x * 4));
}

这是比显式限定 (std::sinstd::cos...) 好的因为很短并且已经能够处理用户定义的浮点类型 (通过参数相关的查找)。

很抱歉,但我强烈反对与此。

@Billy︰ 没有其他的方法来支持调用 userlib::cos(userlib::superint)。每个功能都有一种用法。

@Zan︰ 当然没有。using std::cos;using std::sin等。然而,问题是,任何设计良好的userlib将具有其sincos在自己的命名空间,因此这实际上不能帮助您。(除非using namespace userlib此模板之前即为那样糟糕using namespace std-和存在的范围并不局限。)此外,像这样我曾看到过这一点到唯一的功能是swap,并在这种情况下我建议使用刚创建的std::swap模板专用化和避免整个问题。

@BillyONeal:template<typename T> void swap(MyContainer<T>&, MyContainer<T>&) (没有任何函数模板部分专用化 (ftp) 将另,因此有时需要求助于改为重载。

@BillyONeal︰ 您 (7-时间-upvoted !) 的评论是错误--您描述的情况完全是 ADL 的被设计来覆盖。简言之,如果x有一个或多个"相关联的命名空间"(如namespace userlib中定义了它时) 然后任何函数调用看起来像cos(x)另外查看这些命名空间,而无需任何using namespace userlib;事先所必需。Zan Lynx 是适当 (和 c + + 名称查找是 byzantine...)

请输入您的翻译

Why is “using namespace std” in C++ considered bad practice?

确认取消