你更喜欢在C++中使用显式命名空间还是'using'关键字?

17
当使用C++命名空间时,您是否更喜欢显式地命名它们,像这样:
std::cout << "Hello, world!\n";

或者你更喜欢使用 using namespace

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

如果您更喜欢后者,那么您是在文件范围还是函数范围内声明您的using语句呢?

个人倾向于显式地命名它们-这样打字更多,但是当使用混合命名空间时(例如stdboost),我发现它更易读。

8个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
20

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


1
直到你因为显式指定命名空间而错过了一个模板特化,才会感到痛苦。我必须承认,出于习惯,我也会这样做,但自从阅读了Meyer的《Effective C ++》以后,我更加有意识地思考这个问题。 - oz10
这只是在实践中对我来说一直是min和max的问题,更糟糕的是由于MS头文件也执行了#define min和max。 - paulm

20

额外的类型输入并不是问题所在。 显式限定名称的问题在于视觉混乱。 让我们面对现实吧,C ++语法很不整洁。 没有必要使名称变得更长并且在代码中大量使用 ::,这只会让情况变得更糟。

我赞同Jeff Atwood的看法:最好的代码是没有代码。 这是非常正确的。

命名空间导入是减少杂乱无用代码的好方法,没有任何缺点:只要打开的命名空间的范围被限制为单个编译单元1,如果出现名称冲突,解决起来也很容易。

为什么显式名称(通常)应该更可读,一直是个谜。读者通常应该足够了解代码,以便能够推断出语义。如果他们不知道,那么代码需要修复。


1) 推论:头文件中不要使用 using


我认为“视觉混乱”是一个奇怪的观点,如果std::如此糟糕,那么为什么还要使用C++呢? - paulm
@paulm,我完全不理解你的论点。它听起来有些挖苦:仅仅因为C++通常比较冗长,这并不意味着我们不能改进我们的代码。 - Konrad Rudolph

17

我总是在std和boost中使用using namespace。除非一个命名空间被频繁使用并且会使代码混乱,否则我倾向于使用显式的命名空间。

在头文件中,为了避免污染#including源的全局命名空间,我从不使用using namespace


4

我的通用规则是在头文件中始终明确地使用命名空间,而在代码中通常使用using语句。前者的原因是在每个定义的部分都清楚地说明正在使用什么,后者的原因是它使得在必要时使用来自另一个命名空间的替代变得容易。例如,如果我们想开始使用foo::string而不是std::string,我们只需要更新头文件和using语句,而不是在代码中替换每个std::string实例为foo::string。

当然,这对于位于std::命名空间中的类来说就没有那么有用了,因为即使您替换一个类,您仍然可能会使用其他std中的类,并且可能会遇到歧义问题,但这只是一个示例。


4

usingusing 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
}

2

只有在存在歧义的情况下才使用显式命名空间。这样更易读,但额外的键入过于繁琐,并且您必须假设其他开发人员具有标准库的基本熟悉度。

我仅在以下两种情况下拼写命名空间:一是当我只使用它一两次,例如添加一个快速调试语句,二是当我使用一些非标准库时。

我通常在文件范围内声明命名空间,但如果您混合使用命名空间,则将其声明放置在函数范围内更为合适。


2

using 在函数作用域中使用,或者如果函数非常小(通常是这样),则只需显式命名空间。


2
我倾向于在 .cpp 文件的顶部显式导入我需要的名称,例如:

using std::cout; using std::endl;

这样我可以控制我使用的名称,易于查看其来源,并且代码在使用时不会混乱。 在极少数情况下,如果我需要使用来自不同命名空间的两个名称,则在使用时完全限定它们的命名空间。 我始终在头文件中使用完全限定的名称,几乎不在任何地方使用 'using namespace x'。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,