猿问

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

我已经告诉别人,编写using namespace std代码是错误的,我应该用std::coutstd::cin直接代替。

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


料青山看我应如是
浏览 1484回答 7
7回答

MM们

这根本与性能无关。但请考虑一下:您正在使用两个名为Foo和Bar的库:using namespace foo;using namespace bar;一切正常,你可以毫无问题地Blah()从Foo和Quux()Bar 打电话。但有一天你升级到新版本的Foo 2.0,它现在提供了一个名为的功能Quux()。现在你遇到了冲突:Foo 2.0和Bar都导入Quux()了你的全局命名空间。这将需要一些努力来修复,特别是如果函数参数碰巧匹配。如果你使用过foo::Blah()和bar::Quux(),然后引进的foo::Quux()将是一个非事件。

吃鸡游戏

Library Foo 2.0可以引入一个函数,Quux()这对于你的一些调用来说Quux()比bar::Quux()你多年来调用的代码更明确地匹配。然后你的代码仍然编译,但它默默地调用错误的函数,并且知道神知道什么。这和事情一样糟糕。请记住,在std命名空间有万吨标识符,其中许多都是很常见的(想想list,sort,string,iterator,等),这是非常有可能出现在其他的代码了。如果你认为这不太可能:在我给出这个答案大约半年之后,在Stack Overflow上有一个问题,其中几乎发生了这种情况(错误的函数被称为由于省略了std::前缀)。这是另一个最近这样一个问题的例子。所以这是一个真正的问题。这里还有一个数据点:很多年前,我也常常发现它必须为标准库中的所有内容添加前缀std::。然后我在一个项目中工作,在开始时决定using禁止指令和声明,除了函数范围。你猜怎么着?我们大部分时间都花了很长时间才习惯编写前缀,经过几周后,我们大多数人甚至同意它实际上使代码更具可读性。这是有原因的:你喜欢更短或更长的散文是主观的,但前缀客观上增加了代码的清晰度。不仅是编译器,而且您也更容易看到引用哪个标识符。十年来,该项目增长了数百万行代码。由于这些讨论一次又一次地出现,我曾经很好奇这个(允许的)功能范围using实际上在项目中的使用频率。我找了它的来源,只发现了一两个地方使用它。对我而言,这表明,一旦尝试过,开发人员std::即使在允许使用指令的情况下,即使每100kLoC使用指令也不会发现痛苦。底线:明确地为所有内容添加前缀不会造成任何伤害,很少习惯,并具有客观优势。特别是,它使编码器和人类读者更容易理解代码 - 这应该是编写代码时的主要目标。

蓝山帝景

放入using namespace类的头文件的问题在于它强制任何想要使用您的类(通过包含头文件)的人也可以“使用”(即看到所有内容)这些其他命名空间。但是,您可以随意在(私有)* .cpp文件中放置using语句。请注意,有些人不同意我这样的说法“感觉自由” - 因为虽然cpp文件中的using语句比标题中的更好(因为它不会影响包含头文件的人),但他们认为它仍然存在没有良好的(因为这取决于它的代码可以使课堂更加难以维持的实现)。这个FAQ主题说,using-directive存在于遗留C ++代码中,并且可以简化向命名空间的转换,但您可能不应该定期使用它,至少不能在新的C ++代码中使用它。FAQ提出两种选择:使用声明:using&nbsp;std::cout;&nbsp;//&nbsp;a&nbsp;using-declaration&nbsp;lets&nbsp;you&nbsp;use&nbsp;cout&nbsp;without&nbsp;qualificationcout&nbsp;<<&nbsp;"Values:";只需输入std ::std::cout&nbsp;<<&nbsp;"Values:";

潇湘沐

不应该在全局范围内使用using指令,尤其是在头文件中。但是,即使在头文件中也存在适当的情况:template&nbsp;<typename&nbsp;FloatType>&nbsp;inlineFloatType&nbsp;compute_something(FloatType&nbsp;x){ &nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;namespace&nbsp;std;&nbsp;//no&nbsp;problem&nbsp;since&nbsp;scope&nbsp;is&nbsp;limited &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;exp(x)&nbsp;*&nbsp;(sin(x)&nbsp;-&nbsp;cos(x&nbsp;*&nbsp;2)&nbsp;+&nbsp;sin(x&nbsp;*&nbsp;3)&nbsp;-&nbsp;cos(x&nbsp;*&nbsp;4));}这比显式限定(std::sin,std::cos...)更好,因为它更短并且能够使用用户定义的浮点类型(通过Argument Dependent Lookup)。
随时随地看视频慕课网APP
我要回答