使用std :: <type> v.s.使用std命名空间

时间:2015-07-16 09:16:43

标签: c++ using

使用using声明的两种方法是

using std::string;
using std::vector;

using namespace std;

哪种方式更好?

=========满意的答案在下面=============

简而言之,在函数内使用声明是无害的,只要给出本地范围的关注,而全局使用声明是危险的,因为它们可能导致命名空间相交,从而使编译器感到困惑。

  

我们经常喜欢在没有命名空间的情况下使用每个名称   资格。这可以通过提供使用声明来实现   对于命名空间中的每个名称,但这很乏味且需要   每次添加或删除新名称时都需要额外的工作   命名空间。或者,我们可以使用using-directive来请求   命名空间中的每个名称都可以在我们的范围内访问   资格。 [...] [...]使用using-directive来制作名字   一个经常使用和知名的图书馆,没有   限定是一种简化代码的流行技术。这是   用于访问标准库设施的技术   书。 [...]在函数中,using-directive可以安全地用作   一个符合标准的便利,但应该注意全球化   using-directives因为过度使用会导致名称冲突   引入了名称空间以避免。 [...]因此,我们必须   注意全局范围中的using-directives。特别是,   不要将using指令放在头文件的全局作用域中   除非在非常特殊的情况下(例如,为了帮助过渡)   因为你永远不知道标题可能在哪里#included。

感谢Jonathan Wakely的报价。

2 个答案:

答案 0 :(得分:8)

取决于。

如果要将单个名称注入另一个范围,则使用声明更好,例如

namespace foolib
{
  // allow vector to be used unqualified within foo,
  // or used as foo::vector
  using std::vector;

  vector<int> vec();

  template<typename T> struct Bar { T t; };

  template<typename T>
  void swap(Bar<T>& lhs, Bar<T>& rhs)
  {
    using std::swap;
    // find swap by ADL, otherwise use std::swap
    swap(lhs.t, rhs.t);
  }
}

但有时你只想要所有的名字,这就是使用指令所做的。这可以在函数中本地使用,也可以在源文件中全局使用。

using namespace置于函数体之外只应该在您确切知道所包含的内容的情况下进行,以便它是安全的(即标题中的,您不知道该怎么做在标题之前或之后被包括在内)尽管很多人仍对这种用法不满(请阅读Why is "using namespace std" considered bad practice?的答案以获取详细信息):

#include <vector>
#include <iostream>
#include "foolib.h"
using namespace foo;  // only AFTER all headers

Bar<int> b;

使用using-directive的一个很好的理由是命名空间只包含少量有意隔离的名称,并且设计为using-directive使用:

#include <string>
// make user-defined literals usable without qualification,
// without bringing in everything else in namespace std.
using namespace std::string_literals;
auto s = "Hello, world!"s;

所以没有一个答案可以说一个普遍优于另一个,它们有不同的用途,每个答案在不同的情况下都更好。

关于using namespace的第一次使用,C ++的创建者Bjarne Stroustrup在 C ++编程语言,第4版的§14.2.3中有这个说法(强调我的) :

  

我们经常喜欢使用命名空间中的每个名称而没有限定条件。这可以通过为命名空间中的每个名称提供using - 声明来实现,但这很繁琐,并且每次在命名空间中添加或删除新名称时都需要额外的工作。或者,我们可以使用using - 指令来请求命名空间中的每个名称都可以在我们的范围内访问而无需限定。 [...]
  [...]使用using - 指令从经常使用的知名库中获取名称,这是一种简化代码的流行技术。 这是本书中用于访问标准库设施的技术。 [...]
  在一个函数中,using - 指令可以安全地用作符号方便,但应该注意全局using - 指令,因为过度使用会导致名称冲突,引入名称空间以避免。 [...]
  因此,我们必须小心using - 全局范围内的指令。特别是,除非在非常特殊的情况下(例如,为了帮助转换),不要在头文件中的全局范围中放置using - 指令,因为您永远不知道标头可能在哪里#include d。

对我来说,这似乎是更好的建议,而不仅仅是坚持它是坏的,不应该使用。

答案 1 :(得分:1)

using std::string;using std::vector;

用一堆符号污染全局命名空间是个坏主意。您也应该只使用std命名空间前缀,因此您知道您正在使用标准库容器。哪个比两个选项 IMO 更好。

如果您只是使用标准库而不是其他任何内容,并且永远不会在您的项目中添加任何其他库,请务必使用using namespace std; - 无论您在这种情况下感觉更舒服。 “从不使用using namespace std;”的惯例来自多个其他库定义诸如stringvector等内容的事实。最好永远不要导入整个命名空间,但在你的情况下它不会引起麻烦。