using std::<type> v.s. using std namespace [重复]

问题描述 投票:2回答:2

使用using声明的两种方法是

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

using namespace std;

哪种方式更好?

c++ using
2个回答
9
投票

这要看情况。

如果你想把一个单独的名字注入到另一个作用域中,那么使用声明更好,如

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);
  }
}

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

using namespace 在函数体之外,只应该在你确切地知道被包含的内容的情况下进行,这样才是安全的(即 在页眉中,你不知道页眉之前或之后会有什么内容)尽管许多人仍然对这种用法皱眉头(请阅读下面的答案 为什么 "使用命名空间std "被认为是不好的做法? 以了解详情)。)

#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 namespaceC++的创造者Bjarne Stroustrup在《C++》一书的14.2.3节中说到 C++编程语言,第4版 (强调是我的)。

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

在我看来,这似乎比仅仅坚持它是坏的,不应该使用的建议要好得多。


1
投票

using std::string; 而且 using std::vector;.

用一堆符号污染全局命名空间是个坏主意。你应该只使用 std 命名空间前缀,所以你知道你使用的是标准的库容器。哪一个比两个选项都好 海事组织.

如果你只是简单地使用标准库,而不是其他,并且永远不会在你的项目中添加任何其他库,那么请使用 using namespace std; - 在那种情况下,只要你觉得比较舒服就可以了。绝不使用 "的惯例。using namespace std;"来自于多个其他库定义了诸如 string, vector 等。好的做法是永远不要导入整个命名空间,但在你的情况下应该不会造成麻烦。

© www.soinside.com 2019 - 2024. All rights reserved.