11

完全重复: 您更喜欢显式命名空间还是 C++ 中的“使用”?

以下哪一项是使用任何命名空间的首选约定?

using namespace std;

或者

using std::cin;
using std::cout;

或者

在代码中需要时调用函数?

std::cout<<"Hello World!"<<std::endl;
4

9 回答 9

14

这里给出了一个很好的解释。

第一种风格,即使用命名空间,违背了命名空间的全部目的。除非在小代码片段中,否则您永远不应该使用它。(我也不在那里使用它!:D)

第二个太冗长了。不实用。

我个人喜欢第三种样式,即输入完全限定的名称(例如std::cout)。

请记住,代码的读取次数比编写次数多得多,并且使用完全限定名称 IMO 使您的代码更具可读性。

于 2009-12-25T17:39:18.873 回答
12

这已经被问过很多次了,但我的 SO 搜索 fu 似乎暂时抛弃了我。基本上:

  • 永远不要在头文件中放置任何类型的 using 指令——这样做会污染你的代码并引入各种难以追踪的错误。

  • using std::string在大量使用此类类型的实现 (.cpp) 文件中首选 using 声明,例如 。

  • 作为最后的手段,使用using namespace std,但只能在实现文件中使用——为了方便,我在 SO 上的可编译代码帖子中使用它。

于 2009-12-25T17:36:57.757 回答
8

这是我在同一主题上写的另一个答案的修改版本。这些问题已经够多了,也许我会得到一个明确的帖子;)

主要问题是名称冲突,因为如果您的代码中有一个名为 cout 的变量using namespace std;,那么您的意思就会模棱两可。不只是cout. count,reverse并且equal也将被包括在内,它们都是常见的标识符。

忽略编译器的所有问题,对于任何来阅读您的代码的人来说也是一个问题。这些额外的 5 个字符可确保下一个维护您的代码的人确切地知道您的意思。


还值得注意的是,你永远不应该把

using namespace std;

在头文件中,因为它可以传播到包含该头文件的所有文件,即使他们不想使用该命名空间。这里的另一个问题是,还不清楚 std 命名空间是否已导入,因此维护者(或 3 个月后的您)添加了一个与包含在同一编译单元中的一些晦涩的 std 函数同名的变量,并且然后花了一个小时试图找出编译错误的原因。

在大多数情况下,使用类似的东西是非常有益的

using std::swap

好像有一个专门的 swap 版本,编译器会使用它,否则它将退回到std::swap. 如果你调用std::swap,你总是使用基本版本,它不会调用专用版本(即使它存在)。

以使用pimpl idiom的代码为例。默认副本可以复制实际实现中的所有数据,而所有需要做的就是交换指针。使用专门的交换可以节省大量的执行时间,设计良好的库应该专门化它。


总之,

  • 总是更using std::swap喜欢std::swap()

  • 由于传播不惜一切代价避免using namespace std在标头中,尽量避免在实现文件中使用它。

  • 每个文件的顶部都有数千个using std::foo不是要走的路。最多将它用于常用类。

其他一切都是意见。

于 2009-12-25T17:44:37.407 回答
3

我个人更喜欢第三种选择。看看这个:

namespace A { int a=0; }
namespace B { int a=0; }

你把它用作:

using namespace A;
using namespace B;
using namespace std;

cout<<a<<endl; //error here!

相反,如果你可以说,

std::cout<<B::a<<std::endl; //No problem, more readable

尽管输入代码可能需要更多时间,但第二个和第三个选项更(某种)更受欢迎。

于 2009-12-25T18:02:28.057 回答
1

这是一个风格问题,但有一件事:您永远不应该将命名空间导入全局范围。例如:

#include <iostream>
using namespace std; // Pollution!

int main()
{
    ....
}

如果要导入命名空间,只需将其导入您正在工作的范围:

#include <iostream>

int main()
{
    using namespace std; // Good!
    ....
}
于 2009-12-25T17:37:19.887 回答
1

我只想指出这using namespace foo是有范围的。例子:

#include <iostream>
#include <vector>
//...
for (int i=0; i<10; ++i)
{
    using namespace std;
    cout << i << endl;
}
vector v; // won't compile

小心使用时,using namespace std它既有用又无害。

于 2009-12-25T19:14:07.327 回答
1

我总是列出完整的命名空间。它提高了可读性并让其他人知道您的函数和数据来自哪里。 using阅读其他人的代码时非常烦人,尤其是当我尝试学习某些东西时,因为我无法判断它是该名称空间的一部分还是其他名称。就像这些其他明智的人所说的那样,它确实打败了命名空间的全部意义,不是吗?关键是将所有内容分开并赋予数据和逻辑意义。

一个要记住的好顺序:最重要的人是使用程序的客户;第二重要的是其他正在维护或尝试从您的代码中学习的编码人员;最不重要的是你。:-)

于 2009-12-25T21:20:23.297 回答
0

当命名空间为 std 时,建议写出完全限定名称是一回事,其中 std:: 仅添加 5 个额外字符。当命名空间堆叠时,这是一个完全“另一个问题”,并且您面临编写如下内容:

if (NumberOfInstances > 0 && (code_type == MyNamespace::MyLongButMeaningfulClassName::EnumDefinedWithinClass::CODE_GREEN ||
                              code_type == MyNamespace::MyLongButMeaningfulClassName::EnumDefinedWithinClass::CODE_YELLOW)) {

特别是如果您有一个公司风格的指导方针,将行数限制为 80 个字符,并且您添加了更多缩进。类似的东西掩盖了所有措辞背后的代码逻辑。那时,为了可读性,您开始欣赏使用和/或本地命名空间别名。

于 2009-12-27T09:55:56.490 回答
-4

无论你喜欢什么。真的,没关系。但是,大多数代码片段使用

using namespace std;
于 2009-12-25T17:34:52.660 回答