目的是什么:“使用命名空间”?

时间:2010-12-05 16:09:43

标签: c++ namespaces using-directives

有令人信服的论据against using namespace std,为什么它会被引入语言呢? using namespace不会破坏名称空间的目的吗?为什么我要写using namespace?是否有任何问题我不知道using namespace优雅地解决了这个问题,可能是using std::swap成语或类似的问题?

6 个答案:

答案 0 :(得分:21)

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

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

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

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

如果在与T相同的命名空间中某些类型的T重载了swap,则会使用该重载。如果您明确调用std::swap,则不会考虑该重载。对于其他类型,这可以追溯到std::swap

BTW,使用声明/指令并没有破坏命名空间的目的,因为你可以在模糊的情况下完全限定名称。

答案 1 :(得分:2)

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

namespace po = boost::program_options;

然后你可以写

po::variables_map ...

答案 2 :(得分:1)

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

BTW,至少对于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 namespace放入namespace 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`
}

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

我发现在使用具有深层嵌套命名空间的库时它很有用。 Boost库就是这样一个例子。在整个地方输入boost::numeric::ublas::matrix<double> m成像...

要避免的是在头文件中执行using namespace,因为这有可能使任何包含所述标题的程序搞砸了。始终将using namespace语句放在.cpp / .cxx文件中,以便它仅限于文件范围。

答案 5 :(得分:-1)

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

中包含的类,对象和函数集

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