c ++ - 为什么“使用命名空间std”被认为是不好的做法?

其他人告诉我,在代码中编写using namespace std是错误的,我应该直接使用stdstd::cin

为什么using namespace std被认为是不好的做法? 是低效还是冒着声明模糊变量(与std命名空间中的函数具有相同名称的变量)的风险? 它会影响性能吗?

akbiggs asked 2018-11-26T14:40:25Z
30个解决方案
1832 votes

这根本与性能无关。 但请考虑一下:您正在使用两个名为Foo和Bar的库:

using namespace foo;
using namespace bar;

一切正常,你可以从Foo拨打foo::Blah(),从Bar拨打bar::Quux()没问题。 但有一天你升级到新版本的Foo 2.0,它现在提供了一个名为foo::Quux()的功能。现在你有一个冲突:Foo 2.0和Bar都将Quux()导入你的全局命名空间。 这将需要一些努力来修复,特别是如果函数参数碰巧匹配。

如果你曾经使用过foo::Blah()bar::Quux(),那么引入foo::Quux()本来就是非事件。

Greg Hewgill answered 2018-11-26T14:40:41Z
1195 votes

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

Library Foo 2.0可能会引入一个函数Quux(),这对于你的using的一些调用比你多年来调用的std::更明确地匹配。 然后你的代码仍然编译,但它默默地调用错误的函数并且知道神知道什么。 事情就像事情一样糟糕。

请记住,using命名空间有很多标识符,其中许多是非常常见的(想想std::,sort,string,iterator等),它们很可能也出现在其他代码中。

如果你认为这不太可能:在我给出这个答案大约半年之后,在Stack Overflow上有一个问题,其中几乎发生了这种情况(错误的函数被称为由于省略了using前缀)。 这是另一个最近这样一个问题的例子。所以这是一个真正的问题。


这是另外一个数据点:很多年前,我也常常发现它很烦人,必须在标准库中添加前缀using。然后我在一个项目中工作,在开始时决定std::指令和声明都是 除功能范围外被禁止。 你猜怎么着? 我们大部分时间都花了很长时间才习惯编写前缀,经过几周后,我们大多数人甚至同意它实际上使代码更具可读性。 这是有原因的:你喜欢更短或更长的散文是主观的,但前缀客观上增加了代码的清晰度。 不仅是编译器,而且您也发现更容易看到引用了哪个标识符。

十年来,该项目增长了数百万行代码。 由于这些讨论一次又一次地出现,我曾经很好奇这个(允许的)功能范围using实际上在项目中使用的频率。 我找到它的来源,只找到了一两个地方使用它。 对我而言,这表明,一旦尝试过,开发人员就不会发现std::甚至每100kLoC使用指令也很痛苦,即使在允许使用它的情况下也是如此。


底线:明确地为所有内容添加前缀不会造成任何伤害,很少习惯,并具有客观优势。 特别是,它使编码器和人类读者更容易理解代码 - 这应该是编写代码时的主要目标。

sbi answered 2018-11-26T14:41:31Z
325 votes

std::cout << "Values:"; 放在类的头文件中的问题在于它强制任何想要使用您的类(通过包含头文件)的人也可以“使用”(即看到所有内容)这些其他命名空间。

但是,您可以随意在(私有)* .cpp文件中放置using语句。


请注意,有些人不同意我的说法“感觉自由”,因为虽然cpp文件中的using语句比标题中的更好(因为它不会影响包含头文件的人),但他们认为它仍然存在 不好(因为根据代码,它可能使类的实现更难维护)。 这个FAQ主题说,

using-directive存在于遗留C ++代码中,并且可以简化向命名空间的转换,但您可能不应该定期使用它,至少不应该在新的C ++代码中使用它。

FAQ提出了两种选择:

  • 使用声明:

    std::cout << "Values:";
    
  • 只需输入std ::

    std::cout << "Values:";
    
ChrisW answered 2018-11-26T14:42:24Z
209 votes

我最近遇到了关于Visual Studio 2010的投诉。事实证明,几乎所有的源文件都有这两行:

using namespace std;
using namespace boost;

很多Boost功能都进入了C ++ 0x标准,Visual Studio 2010有很多C ++ 0x功能,所以突然间这些程序没有编译。

因此,避免使用using namespace X;是一种面向未来的形式,这种方法可以确保对正在使用的库和/或头文件的更改不会破坏程序。

David Thornley answered 2018-11-26T14:42:53Z
172 votes

简短版本:不要在头文件中使用全局使用声明或指令。 随意在实现文件中使用它们。 以下是Herb Sutter和Andrei Alexandrescu在C ++编码标准中对此问题所说的内容(重点强调是我的):

摘要

命名空间使用是为了您的方便,而不是让您对其他人造成:在#include指令之前,切勿编写using声明或using指令。

推论:在头文件中,不要使用指令或使用声明来编写命名空间级别; 相反,显式命名空间限定所有名称。 (第二条规则从第一条开始,因为标题永远不会知道其他标题#includes可能会出现在它们之后。)

讨论

简而言之:在#include指令之后,你可以而且应该在你的实现文件中使用声明和指令来使用命名空间,并且感觉良好。 尽管反复断言,使用声明和指令的命名空间并不是邪恶的,并且它们不会破坏命名空间的目的。 相反,它们是使命名空间可用的原因。

mattnewport answered 2018-11-26T14:43:36Z
108 votes

不应该在全局范围内使用using指令,尤其是在头文件中。 但是,即使在头文件中也存在适当的情况:

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::sin,std::cos ...)因为它更短并且能够使用用户定义的浮点类型(通过Argument Dependent Lookup)。

robson3.14 answered 2018-11-26T14:44:02Z
84 votes

不要在全球范围内使用它

只有在全球使用时才被视为“坏”。 因为:

  • 你混乱了编程的命名空间。
  • 当你使用很多std::swap时,读者很难看到特定标识符的来源。
  • 对于其他读者来说,无论你的源代码是什么,对于最常见的读者来说更是如此:你自己。 一两年后回来看看......
  • 如果你只是谈论std::swap,你可能不知道你抓到的所有东西 - 当你添加另一个value_或转移到新的C ++版本时,你可能会得到你不知道的名称冲突。

您可以在本地使用它

继续在本地(几乎)自由使用它。 当然,这可以防止你重复std::swap - 重复也很糟糕。

在本地使用它的习语

在C ++ 03中有一个成语 - 样板代码 - 用于为您的类实现std::swap函数。 有人建议您实际使用本地value_ - 或至少void std::swap(int, int)

class Thing {
    int    value_;
    Child  child_;
public:
    // ...
    friend void swap(Thing &a, Thing &b);
};
void swap(Thing &a, Thing &b) {
    using namespace std;      // make `std::swap` available
    // swap all members
    swap(a.value_, b.value_); // `std::stwap(int, int)`
    swap(a.child_, b.child_); // `swap(Child&,Child&)` or `std::swap(...)`
}

这有以下魔力:

  • 编译器将为value_选择std::swap,即void std::swap(int, int)
  • 如果你有一个重载std::swap实现编译器会选择它。
  • 如果你没有那个重载,编译器将使用std::swap并尝试最好地交换这些。

使用C ++ 11,没有理由再使用这种模式。 std::swap的实施已更改为找到潜在的过载并选择它。

towi answered 2018-11-26T14:45:23Z
72 votes

如果导入正确的头文件,则突然在全局范围内使用hex,std::,std::std::等名称。 如果您不知道std::包含这些名称,这可能会令人惊讶。 如果你也尝试在本地使用这些名称,可能会引起一些混乱。

如果所有标准内容都在自己的命名空间中,则不必担心与代码或其他库的名称冲突。

sth answered 2018-11-26T14:45:49Z
37 votes

有经验的程序员使用任何解决问题的方法,避免出现任何问题,并且出于这个原因,他们避免使用头文件级别的使用指令。

有经验的程序员也会尽量避免在源文件中对名称进行完全限定。 造成这种情况的一个次要原因是,除非有充分的理由,否则在代码较少时编写更多代码并不优雅。 这样做的一个主要原因是关闭依赖于参数的查找(ADL)。

这些好理由是什么? 有时程序员明确想要关闭ADL,有时他们想要消除歧义。

所以以下都可以:

  1. 函数级实现中的函数级using指令和using声明
  2. 源文件中的源文件级使用声明
  3. (有时)源文件级使用指令
Alexander Poluektov answered 2018-11-26T14:46:35Z
35 votes

我同意它不应该在全球范围内使用,但在本地使用并不是那么邪恶,就像在His_lib::String中一样。这是“C ++编程语言”的一个例子:

namespace My_lib {

    using namespace His_lib; // everything from His_lib
    using namespace Her_lib; // everything from Her_lib

    using His_lib::String; // resolve potential clash in favor of His_lib
    using Her_lib::Vector; // resolve potential clash in favor of Her_lib

}

在这个例子中,我们解决了潜在的名称冲突和由其组成引起的歧义。

在那里显式声明的名称(包括由using声明声明的名称,如His_lib::String)优先于using-directive(using namespace Her_lib)在另一个作用域中可访问的名称。

Oleksiy answered 2018-11-26T14:47:05Z
35 votes

另一个原因是惊喜。

如果我看到cout,而不是cout

我想这是什么cout? 这是正常的cout吗? 这是特别的吗?

Martin Beckett answered 2018-11-26T14:47:34Z
24 votes

我也认为这是一种不好的做法。 为什么? 只有一天,我认为命名空间的功能是划分东西,所以我不应该把所有东西扔到一个全球包中来破坏它。但是,如果我经常使用'cout'和'cin',我在cpp文件中写道:using std::cout; using std::cin;(从不在头文件中,因为它传播的是#include)。 我认为没有人会说出一个流coutcin。;)

Yelonek answered 2018-11-26T14:47:55Z
19 votes

这一切都与管理复杂性有关。 使用命名空间会拉出你不想要的东西,因此可能使调试变得更难(我说可能)。 在整个地方使用std ::更难阅读(更多文字和所有内容)。

课程的马匹 - 管理你的复杂性,你最好能和最好的能力。

Preet Sangha answered 2018-11-26T14:48:22Z
19 votes

很高兴看到代码并知道它的作用。 如果我看到cout << 1;我就知道这是coutcout流的流。 如果我看到cout然后我不知道。 它可能是std库的cout流。 或者在同一功能中可能有int cout = 0;十行。 或者该文件中名为coutstatic变量。 它可能是任何东西。

现在花费一百万行代码库,这不是特别大,你正在寻找一个bug,这意味着你知道这一百万行中有一行不能完成它应该做的事情。 cout << 1;可以读取名为coutstatic int,将其向左移一位,然后丢弃结果。 寻找一个bug,我必须检查一下。 你能看到我真的更喜欢看std::cout吗?

如果你是一名教师而且从来没有必要编写和维护任何代码,那么这些东西似乎是一个非常好的主意。 我喜欢看代码,其中(1)我知道它的作用; 并且,(2)我有信心写作它的人知道它做了什么。

gnasher729 answered 2018-11-26T14:48:54Z
16 votes
  1. 你需要能够阅读那些与你有不同风格和最佳实践意见的人所编写的代码。

  2. 如果你只使用cout,没有人会感到困惑。 但是当你有大量的命名空间飞来飞去并且你看到这个类而你并不完全确定它的作用时,将命名空间显式化作为一种评论。 乍一看,你可以看到'哦,这是一个文件系统操作'或'那就是做网络的东西'。

Dustin Getz answered 2018-11-26T14:49:21Z
16 votes

同时使用许多命名空间显然是灾难的一个方法,但是在我看来,使用JUST命名空间std并且只有命名空间std并不是一件大事,因为重新定义只能通过您自己的代码进行...

所以只需将它们的功能视为保留名称,如“int”或“class”,就是这样。

人们应该停止这么肛门。 你的老师一直都是对的。 只需使用ONE命名空间; 这是首先使用命名空间的重点。 您不应该同时使用多个。 除非是你自己的。 因此,重新定义不会发生。

user2645752 answered 2018-11-26T14:49:51Z
15 votes

考虑

// myHeader.h
#include <sstream>
using namespace std;


// someoneElses.cpp/h
#include "myHeader.h"

class stringstream {  // uh oh
};

请注意,这是一个简单的示例,如果您有包含20个包含和其他导入的文件,您将有大量的依赖关系来解决问题。 更糟糕的是,根据冲突的定义,您可以在其他模块中获得无关的错误。

这并不可怕,但你不会在头文件或全局命名空间中使用它来避免头痛。 在非常有限的范围内完成它可能是正常的,但我输入额外的5个字符以解释我的功能来自哪里我从未遇到过问题。

Ron Warholic answered 2018-11-26T14:50:20Z
10 votes

命名空间是命名范围。 命名空间用于对相关声明进行分组并保持分离物品分开。 例如,两个单独开发的库可以使用相同的名称来表示不同的名称项目,但用户仍然可以使用两者:

namespace Mylib{
    template<class T> class Stack{ /* ... */ };
    / / ...
}
namespace Yourlib{
    class Stack{ /* ... */ };
    / / ...
}
void f(int max) {
    Mylib: :Stack<int> s1(max) ; / / use my stack
    Yourlib: :Stack s2(max) ; / / use your stack
    / / ...
}

重复命名空间名称可能会分散读者和作者的注意力。 因此,这是可能的声明在没有明确限定的情况下可以使用特定命名空间中的名称。 例如:

void f(int max) {
    using namespace Mylib; / / make names from Mylib accessible
    Stack<int> s1(max) ; / / use my stack
    Yourlib: :Stack s2(max) ; / / use your stack
    / / ...
}

命名空间为管理不同的库和不同版本的库提供了强大的工具     码。 特别是,它们为程序员提供了如何明确地引用非本地语言的替代方案     名称。

来源:C ++编程语言概述作者:Bjarne Stroustrup

Rohan Singh answered 2018-11-26T14:50:54Z
10 votes

一个澄清问题的具体例子。 想象一下,你有一个情况,你有2个库,foo和bar,每个库都有自己的命名空间:

namespace foo {
    void a(float) { /* does something */ }
}

namespace bar {
    ...
}

现在让我们假设您在自己的程序中使用foo和bar,如下所示:

using namespace foo;
using namespace bar;

void main() {
    a(42);
}

在这一点上一切都很好。 当你运行程序时,它“做了一些事情”。 但是后来你更新吧,让我们说它已经变成了:

namespace bar {
    void a(float) { /* does something completely different */ }
}

此时您将收到编译器错误:

using namespace foo;
using namespace bar;

void main() {
    a(42);  // error: call to 'a' is ambiguous, should be foo::a(42)
}

所以你需要做一些维护来澄清你的意思(即foo::a)。 这可能是不可取的,但幸运的是它很容易(只需在bar::a的所有调用前添加a(42),编译器标记为不明确)。

但想象一下另一种方案,其中bar改为看起来像这样:

namespace bar {
    void a(int) { /* does something completely different */ }
}

此时您对a(42)的调用突然绑定到bar::a而不是foo::a,而不是做'某事'它'完全不同'。 没有编译器警告或任何东西 你的程序只是默默地开始做一些与以前完全不同的事情。

当您使用命名空间时,您会冒这样的情况,这就是人们使用命名空间感到不舒服的原因。 命名空间中的事物越多,冲突的风险就越大,因此人们使用命名空间std(由于该命名空间中的事物数量)比其他命名空间更令人不舒服。

最终,这是可写性与可靠性/可维护性之间的权衡。 可读性也可以考虑,但我可以看到这种论点的论点。 通常我会说可靠性和可维护性更重要,但在这种情况下,您将不断支付可写性成本,以获得相当罕见的可靠性/可维护性影响。 “最佳”权衡取决于您的项目和优先事项。

Kevin answered 2018-11-26T14:51:52Z
8 votes

使用命名空间std的示例由于计数的模糊性而引发编译错误,这也是算法库中的函数。

#include <iostream>

using namespace std;

int count = 1;
int main() {
    cout<<count<<endl;
}
Nithin answered 2018-11-26T14:52:14Z
8 votes

我同意这里的其他人,但是想解决有关可读性的问题 - 你可以通过在文件,函数或类声明的顶部使用typedef来避免所有这些问题。

我通常在我的类声明中使用它,因为类中的方法倾向于处理类似的数据类型(成员),而typedef是指定在类的上下文中有意义的名称的机会。 这实际上有助于类方法定义的可读性。

//header
class File
{
   typedef std::vector<std::string> Lines;
   Lines ReadLines();
}

并在实施中:

//cpp
Lines File::ReadLines()
{
    Lines lines;
    //get them...
    return lines;
}

而不是:

//cpp
vector<string> File::ReadLines()
{
    vector<string> lines;
    //get them...
    return lines;
}

要么:

//cpp
std::vector<std::string> File::ReadLines()
{
    std::vector<std::string> lines;
    //get them...
    return lines;
}
Carl answered 2018-11-26T14:52:52Z
7 votes

“为什么'使用命名空间std;' 在C ++中被认为是一种不好的做法?“

我把它反过来说:为什么输入5个额外的字符被一些人认为是麻烦的?

考虑例如 编写一个数字软件,当“向量”是问题域最重要的概念之一时,为什么我会考虑通过将一般的“std :: vector”切换为“向量”来污染我的全局命名空间?

Solkar answered 2018-11-26T14:53:23Z
6 votes

在所有条件下,我认为这不一定是不好的做法,但是在使用它时需要小心。 如果您正在编写库,则可能应该使用范围分辨率运算符和命名空间来保持库与其他库的对接。 对于应用程序级代码,我没有看到任何错误。

Dr. Watson answered 2018-11-26T14:53:47Z
5 votes

为了回答你的问题,我实际上以这种方式看待它:许多程序员(不是全部)调用命名空间std。 因此,人们应该养成不使用与命名空间std中的名称相同或使用相同名称的东西。 这是一个很大的问题,但与严格来说可能提出的可能连贯的单词和假名的数量相比,并没有那么多。

我的意思是真的......说“不要依赖于存在”只是让你依赖它不存在。 你经常会有问题借用代码片段并不断修复它们。 只需保留用户定义和借用的东西,因为它们应该是有限范围的,并且非常不使用全局变量(诚然,全局变量应该是“现在编译,后来理智”的最后手段)。 真的,我认为这是你老师的坏建议,因为使用std将同时适用于“cout”和“std :: cout”,但不使用std只适用于“std :: cout”。 你并不总是有幸写下你自己的代码。

注意:在实际了解编译器的工作原理之前,不要过分关注效率问题。 通过一些编码经验,在您意识到他们能够将优秀代码概括为简单的东西之前,您不必了解它们。 每一点都很简单,好像你用C编写了整个东西。好的代码只是它需要的复杂。

Noneyo Getit answered 2018-11-26T14:54:21Z
5 votes

我同意其他人的意见 - 它要求名称冲突,含糊不清,然后事实是它不那么明确。 虽然我可以看到使用std,但我个人的偏好是限制它。 我也会强烈考虑其他人指出的内容:

如果要查找可能是相当常见名称的函数名称,但您只想在std名称空间中找到它(或者反过来 - 您要更改名称空间boost::regex:: ...中不存在的所有调用,名称空间string,.. 。),那你怎么建议这样做? 您可以编写一个程序来执行此操作,但是花时间处理项目本身而不是编写程序来维护项目不是更好吗?

我个人实际上不介意std前缀。 我喜欢这种外观而不是拥有它。 我不知道是不是因为它是明确的并且对我说“这不是我的代码......我正在使用标准库”或者如果它是其他东西,但我认为它看起来更好。 这可能是奇怪的,因为我最近才进入C ++(使用并且仍然使用C和其他语言的时间更长,C是我最喜欢的语言,正好在汇编之上)。

还有一件事虽然它与上述有些相关,但其他人指出了什么。 虽然这可能是不好的做法,但有时我会为标准库版本保留std,并为程序特定的实现命名。 是的确这可能会咬你并且咬你很难但这一切都归结为我从头开始这个项目而且我是唯一的程序员。 示例:我重载boost::regex:: ...并将其命名为string.我有一些有用的补充。 我之所以这样做是因为我的C和Unix(+ Linux)倾向于小写名称。

除此之外,您还可以拥有名称空间别名。 以下是一个可能未被引用的示例。 我使用C ++ 11标准,特别是libstdc ++。 好吧,它没有完整的std支持。 当然它会编译,但它会引发异常,因为它是程序员端的错误。 但缺乏实施。 所以这就是我解决它的方式。 安装Boost的正则表达式,将其链接。然后,我执行以下操作,以便当libstdc ++完全实现它时,我只需删除此块并且代码保持不变:

namespace std
{
    using boost::regex;
    using boost::regex_error;
    using boost::regex_replace;
    using boost::regex_search;
    using boost::regex_match;
    using boost::smatch;
    namespace regex_constants = boost::regex_constants;  
}

我不会争论这是不是一个坏主意。 然而,我会争辩说它为我的项目保持干净,同时使其具体:真的我必须使用Boost但我正在使用它,就像libstdc ++最终将拥有它。 是的,开始您自己的项目并从一开始就使用标准(...)开始,这有助于维护,开发以及项目涉及的所有内容!

编辑:
现在我有时间,只是澄清一些事情。我实际上并不认为在故意使用STL中的类/任何名称来更好地代替。对于我来说,字符串是异常(忽略第一个,上面或第二个,如果必须,请忽略),因为我不喜欢'String'的想法。事实上,我仍然偏向于C并且偏向于C ++。保留细节,我工作的大部分内容更适合C(但这是一个很好的练习和一个很好的方法,使自己成为一个。学习另一种语言和b。尽量不要偏向于对象/类/等等,这可能是更好的陈述不那么封闭,不那么傲慢,更容易接受。但是有用的是一些人已经提出的建议:我确实使用了list(它是相当通用的,不是吗?),排序(同样的事情)来命名两个如果我要做std会导致名称冲突等等最后我更喜欢具体,控制和知道,如果我打算将它作为标准用途,那么我将不得不指定它。简单地说:不假设允许。

至于使Boost的正则表达式成为std的一部分。我这样做是为了未来的整合 - 再次,我完全承认这是偏见 - 我不认为它像boost::regex:: ...那样难看。事实上这对我来说是另一回事。 在C ++中有许多东西我还没有完全接受外观和方法(另一个例子:可变参数模板与var args [尽管我承认可变参数模板非常有用!])。 即使那些我接受它的人也很困难,我仍然遇到问题。

tambre answered 2018-11-26T14:55:25Z
5 votes

它不会使您的软件或项目性能变差,在源代码开头包含命名空间也不错。 包含namespace std指令会根据您的需要以及您开发软件或项目的方式而有所不同。

namespace std包含C ++标准函数和变量。 当您经常使用C ++标准函数时,此命名空间很有用。

如本页所述:

使用命名空间std的语句通常被认为是错误的   实践。 此声明的替代方法是指定   标识符所属的命名空间使用范围运算符(::)   每次我们声明一个类型。

并看到这个意见:

在源文件中使用“using namespace std”没有问题   当你大量使用命名空间并确定这一点时   没有什么会碰撞。

有些人说在源文件中包含using namespace std是一种不好的做法,因为你从该命名空间调用了所有的函数和变量。 如果要定义一个与namespace std中包含的另一个函数同名的新函数,则会使函数重载,并且由于编译或执行可能会产生问题。 它不会像你期望的那样编译或执行。

如本页所述:

虽然该语句使我们无法输入std :: when   我们希望访问std命名空间中定义的类或类型   将整个std命名空间导入当前命名空间   该计划。 让我们举几个例子来理解为什么会这样   可能不是一件好事

...

现在处于开发的后期阶段,我们希望使用另一个版本   在一些名为“foo”的库中自定义实现的cout(for   例)

...

请注意cout指向哪个库有歧义?   编译器可能会检测到这一点,而不是编译程序。 在最坏的情况下   例如,程序可能仍然编译但调用错误的函数,因为   我们从未指定标识符属于哪个命名空间。

CryogenicNeo answered 2018-11-26T14:56:31Z
4 votes

使用非限定导入标识符,您需要外部搜索工具(如grep)来查找声明标识符的位置。 这使得关于程序正确性的推理更加困难。

August Karlstrom answered 2018-11-26T14:56:51Z
4 votes

这取决于它的位置。 如果它是一个公共头,那么你通过将它合并到全局命名空间来减少命名空间的值。 请记住,这可能是制作模块全局变量的一种巧妙方法。

MathGladiator answered 2018-11-26T14:57:12Z
4 votes

根据我的经验,如果您有多个库使用说,using namespace std;,但出于不同的目的,您可能使用错误的using namespace otherlib;

例如,如果我键入,using namespace std;using namespace otherlib;并键入cout(恰好是两者),而不是std::cout(或'otherlib::cout'),您可能使用错误的一个,并获得错误,它更有效和高效 使用std::cout

Engine Dev answered 2018-11-26T14:57:37Z
4 votes

这是一种不好的做法,通常称为全局名称空间污染。 当多个命名空间具有相同的带有签名的函数名时,可能会出现问题,然后编译器决定调用哪一个将是不明确的,当您使用函数调用std::cout指定命名空间时,这一切都可以避免。 希望这可以帮助。:)

adn.911 answered 2018-11-26T14:57:58Z
translate from https://stackoverflow.com:/questions/1452721/why-is-using-namespace-std-considered-bad-practice