17

使用 C++ 命名空间时,您是否更喜欢显式命名它们,如下所示:

std::cout << "Hello, world!\n";

还是您更喜欢using namespace

using namespace std;
cout << "Hello, world!\n";

如果您更喜欢后者,您是否在文件或函数范围内声明您的使用?

就我个人而言,我更喜欢明确地命名它们——它的类型更多,但是当使用混合命名空间(例如stdboost)时,我发现它更具可读性。

4

8 回答 8

20

我总是使用明确的。写 std 不会伤害我,我清楚地看到它来自哪里。当您有一些遗留项目需要使用它自己的“字符串”、“向量”等来维护时,它会很有用。代码携带的信息越多越好。

于 2008-10-18T11:39:13.340 回答
20

额外的输入不是这里的问题。显式限定名称的问题是视觉混乱。让我们面对现实吧,C++ 语法是杂乱无章的。无需通过不必要地延长名称并在代码中大量使用::s 来使情况变得更糟。

我和 Jeff Atwood 在一起:最好的代码就是没有代码。这是真的。

命名空间导入是减少混乱的好方法,没有任何缺点:只要打开的命名空间的范围减少到单个编译单元1,如果出现名称冲突,就可以轻松解决。

为什么显式名称应该(通常)更具可读性对我来说一直是个谜。读者通常应该对代码足够了解,以便能够推断出语义。如果不是,则代码无论如何都需要修复。


1)推论:没有using标题!

于 2008-10-18T12:07:24.720 回答
17

我总是using namespace用于标准和提升。其他一切我倾向于使用显式命名空间,除非它使用得太多以至于会使代码混乱。

在标头中,我从不使用using namespace以避免污染#include 源的全局命名空间。

于 2008-10-18T11:35:34.083 回答
4

我的一般规则是始终在标头中显式使用命名空间,并且通常在代码中使用 using。前者的原因是在定义的每个部分中明确说明正在使用什么,而后者的原因是如果有必要,它可以很容易地使用来自另一个命名空间的替换。即,如果我们想开始使用 foo::string 而不是 std::string,我们只需要更新标头和 using 语句,而不是在代码中用 foo::string 替换 std::string 的每个实例。

当然,这对于驻留在 std:: 命名空间中的类不太有用,因为即使您替换了一个类,您仍然可能在 std 中使用其他类,并且可能会遇到歧义问题,但这只是一个示例。

于 2008-10-18T12:05:13.197 回答
4

using并且using namespace对于使代码更具可读性非常有用 - 消除混乱。

但在任何情况下,如果很难找出符号的来源,我拒绝导入它的整个命名空间。

我尝试限制导入命名空间的范围:

void bar() {

   // do stuff without vector

   { using std::vector;
      // do stuff with vector
   }

   // do stuff without vector
}

对于“众所周知”的库,比如std,我敢于使用using namespace std. 有理由相信阅读此代码的每个人都知道这些符号。

作为旁注,该using关键字还用于指示派生类还导出其超类的重载成员。

class A {
  void f( A  );
  void f( bool );
};

class B : public A {
  using A::f; // without this, we get a compilation error in foo()
  void f(bool);
};

void foo() {
  B b;
  b.f( A() ); // here's a compilation error when no `using` is used in B
}
于 2008-10-18T15:05:03.923 回答
2

当有一些歧义时,我只使用显式命名空间。它更具可读性,但是额外的输入太乏味了,并且您必须假设其他开发人员对标准库具有基本的熟悉程度。

我拼写命名空间的唯一其他时间是我只使用它一次或两次,例如添加快速调试语句,或者我正在使用一些非标准库。

我通常在文件范围内声明命名空间,但如果您正在混合命名空间,则将声明放在更接近使用它的点(在函数范围内)可能是有意义的。

于 2008-10-18T11:37:51.567 回答
2

using在函数范围内,或者如果函数非常小(通常是),只需显式命名空间

于 2008-10-18T13:09:49.103 回答
2

我倾向于在 .cpp 文件的顶部显式导入我需要的名称,所以......

使用 std::cout;使用 std::endl;

ETC...

这样我就可以控制我使用的名称,并且很容易看到它们的来源,并且代码在使用时不会混乱。

在我使用来自不同命名空间的两个名称的极少数情况下,我会在使用时完全限定它们。

我总是在标题中使用完全限定的名称,并且几乎从不在任何地方使用“使用命名空间 x”...

于 2008-10-18T18:23:29.140 回答