提问人:fredoverflow 提问时间:12/6/2010 最后编辑:Jan Schultkefredoverflow 更新时间:9/21/2023 访问量:6798
“使用命名空间”的目的是什么?
What's the purpose of: "using namespace"?
问:
有令人信服的论据反对,那么为什么它被引入语言中呢?不会破坏命名空间的目的吗?我为什么要写?有没有我不知道的问题,也许是在成语的行中,或者类似的东西,优雅地解决了?using namespace std
using namespace
using namespace
using namespace
using std::swap
答:
首先,这是在命名空间中使用运算符重载的方法(例如using namespace std::rel_ops;
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 声明/指令不会破坏命名空间的目的,因为在出现歧义的情况下,您始终可以完全限定名称。
评论
大多数时候,它只是编写代码的快捷方式。您可以将名称导入到封闭的上下文中。我通常将它限制为文件,因为当您将 using 指令包含在文件中时,它会污染包含它的所有文件。另一个好的做法是将环境限制在尽可能封闭的环境中,例如,在方法主体声明内部。我认为它是一种方便,仅此而已,类似于命名空间别名,例如:.cpp
.h
using namespace
namespace po = boost::program_options;
然后你可以写
po::variables_map ...
人们特别反对,但不反对;或者引用(如果你明白我的意思,那就是使用命名空间,只是不是它。此外,大多数反对意见都在头文件中。在可以立即看到效果的源文件中,它的危害较小。using namespace std;
using namespace BigCorp
std::cout
using
using namespace std
命名空间是一个非常有用的概念,它允许我拥有一个名为 Date 的类,即使我使用的库有一个名为 Date 的类。在将它们添加到语言中之前,我们必须有类似 和 的东西(我的公司 Gregory Consulting 早于)。使用命名空间(带或不带关键字)可以让我们编写更干净、更整洁的代码。但是当你每次都不得不说时,你就失去了更干净、更整洁的部分。 [免责声明:我实际上不再使用我自己的字符串类了 - 想象一下一些适当的名称冲突。这就是这句话的魅力所在。不要将它放在标头之外,不要将其应用于 ,您通常应该避免麻烦。GCDate
GCString
std::string
using
Gregcons::string
using
std
评论
using namespace foo
using foo::whatever
using std::cout
我发现它在使用具有深度嵌套命名空间的库时很有用。Boost 库就是这样一个例子。到处都是成像打字......boost::numeric::ublas::matrix<double> m
要避免的事情是在头文件中执行,因为这有可能严重搞砸包含所述标头的任何程序。始终将语句放在 .cpp/.cxx 文件中,以便将其限制为文件范围。using namespace
using namespace
评论
matrix
typedef boost::numeric::ublas::matrix<double> DoubleMatrix
DoubleMatrix
“命名空间允许将类、对象和函数等实体分组到一个名称下。这样,全局范围可以划分为“子范围”,每个子范围都有自己的名称。其中 identifier 是任何有效的标识符,entities 是命名空间中包含的类、对象和函数的集合”
更多信息请见:http://www.cplusplus.com/doc/tutorial/namespaces/
引入的主要原因是向后兼容性:如果您有很多使用大量(标准版本的)标准库函数和类的预命名空间代码,则需要一种简单的方法来使该代码与符合标准的编译器一起使用。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 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`
}
评论
#include <iostream.h>
cin
cout
std::