17

有令人信服的论据反对 using namespace std,那么为什么将它引入语言中呢?不会using namespace破坏命名空间的目的吗?我为什么要写作using namespace?有什么我不知道的问题可以通过 优雅地解决using namespace,也许是using std::swap成语或类似的东西?

4

6 回答 6

21

一方面,这是在命名空间中使用运算符重载的方法(例如using namespace std::rel_ops;or using namespace boost::assign;

简洁也是一个强有力的论据。你真的会喜欢打字和阅读std::placeholders::_1而不是阅读_1吗?此外,当您以函数式风格编写代码时,您将在命名空间中使用无数std对象boost

另一个重要的用法(尽管通常不导入整个命名空间)是启用参数相关的查找:

template <class T>
void smart_swap(T& a, T& b)
{
    using std::swap;
    swap(a, b);
}

如果 swap 在与 T 相同的命名空间中为某种类型的 T 重载,这将使用该重载。如果您显式调用std::swap,则不会考虑该重载。对于其他类型,这回落到std::swap.

顺便说一句, using 声明/指令不会破坏命名空间的目的,因为在出​​现歧义的情况下,您始终可以完全限定名称。

于 2010-12-05T16:28:46.127 回答
2

大多数时候,它只是编写代码的捷径。您可以将名称导入封闭的上下文中。我通常将它限制在.cpp文件中,因为当您将 using 指令包含到.h文件中时,它会污染包含它的所有文件。另一个好的做法是将 限制在using namespace最封闭的环境中,例如,在方法体声明内部。我认为它是一种方便,仅此而已,并且类似于命名空间别名,例如:

namespace po = boost::program_options;

然后你可以写

po::variables_map ...
于 2010-12-05T16:29:11.913 回答
1

引入的主要原因using namespace是向后兼容性:如果您有大量使用大量(标准前版本)标准库函数和类的前命名空间代码,您需要一种简单的方法来使该代码与符合标准的编译器一起工作.

顺便说一句,至少对于 C++98 而言,依赖于参数的查找规则意味着它using namespace std::rel_ops不会在模板中做你想做的事情(我知道这是否在标准的更高版本中发生了变化)。

例子:

template<typename T> bool bar(T t)
{
  return t > T();
}

namespace foo
{
  class X {};
  bool operator<(X, X);
}

using namespace std::rel_ops;

int main()
{
  X x;
  bar(x); // won't work: X does not have operator>
}

请注意,放入using namespacenamespace foo无济于事。

但是,在正确的位置使用声明会有所帮助:

template<typename T> bool bar(T t)
{
  return t > T();
}

namespace foo
{
  class X {};
  bool operator<(X, X);
  using std::rel_ops::operator>;
}

int main()
{
  X x;
  bar(x); // now works: operator> found per ADL via the using declaration in `namespace foo`
}
于 2013-07-15T00:23:04.197 回答
0

人们特别反对using namespace std;但不反对using namespace BigCorp;或引用(如果您知道我的意思,std::cout它正在使用命名空间,而不是它。)此外,大多数反对意见都在头文件中。在可以立即看到效果的源文件中,它的危害性较小。usingusing namespace std

命名空间是一个非常有用的概念,它允许我拥有一个名为 Date 的类,即使我正在使用的库有一个名为 Date 的类。在将它们添加到语言中之前,我们必须拥有GCDateGCString(我的公司,Gregory Consulting,早于std::string)之类的东西。使用命名空间(带或不带using关键字)让我们都可以编写更干净、更整洁的代码。但是当你每次都必须说Gregcons::string的时候,你有点失去了更干净、更整洁的部分。[免责声明:我实际上不再使用我自己的字符串类 - 想象一些适当的名称冲突。]这就是using声明的吸引力。将其放在标题之外,不要将其应用于std,您通常应该避免麻烦。

于 2010-12-05T16:39:54.583 回答
0

我发现在使用具有深度嵌套命名空间的库时它很有用。Boost 库就是这样一个例子。到处都是成像打字boost::numeric::ublas::matrix<double> m...

要避免的事情是using namespace在头文件中执行,因为这可能会严重破坏任何包含该头文件的程序。始终将using namespace语句放在 .cpp/.cxx 文件中,以便将其限制在文件范围内。

于 2010-12-05T21:16:20.603 回答
-1

“命名空间允许在一个名称下对类、对象和函数等实体进行分组。这种方式可以将全局范围划分为“子范围”,每个子范围都有自己的名称。其中标识符是任何有效标识符,实体是一组命名空间中包含的类、对象和函数”

更多信息在这里: http ://www.cplusplus.com/doc/tutorial/namespaces/

于 2010-12-05T23:49:01.617 回答