为什么每个人都使用未锚定的命名空间声明(即 std:: 不是 ::std::)?

2022-01-14 00:00:00 namespaces c++

在我看来,当有人放入一个恰好与根级命名空间同名的新命名空间并神秘地改变了一大堆程序的含义时,使用非锚定命名空间只是在自找麻烦.那么,为什么人们总是说 std:: 而不是 ::std::.他们真的是想说我想使用任何方便的 std,而不是根目录."?

It seems to me that using unanchored namespaces is just asking for trouble later when someone puts in a new namespace that happens to have the same name as a root level namespace and mysteriously alters the meaning of a whole lot of programs. So, why do people always say std:: instead of ::std::. Do they really mean to be saying "I want to use whatever std is handy, not the root one."?

这是我的意思的一个例子:

Here is an example of what I mean:

在 fred/Foo.h 中:

In fred/Foo.h:

#include <string>

namespace fred {

class Foo {
 public:
   void aPublicMember(const std::string &s);
};

} // end namespace fred

在 fred/Bar.h 中:

In fred/Bar.h:

namespace fred {
namespace std {  // A standard fred component

class string { // Something rather unlike the ::std::string
   // ...
};

} // namespace std

class Bar {
 public:
   void aPublicMember(std::string &s);
};

} // namespace fred

在 oops.cpp 中:

In oops.cpp:

#include <string>
#include "fred/Bar.h"
#include "fred/Foo.h"  // Oops, the meaning of Foo is now different.

这是人们想要的,还是我错过了什么?

Is that what people want, or am I missing something?

也许你说你不应该将命名空间命名为std.这一切都很好,但是其他一些根级命名空间呢?任何人在任何地方定义的任何根级命名空间都应该始终禁止使用子命名空间名称吗?

And maybe you say that you should just never name a namespace std. And that's all well and good, but what about some other root level namespace then? Should any root level namespace anybody ever defines anywhere always be off-limits for a sub-namespace name?

为了澄清,我不会考虑任何告诉我 std 特殊的答案,因为我只是将其用作示例.我说的是一个普遍的问题,我使用 std 作为一个道具来说明它,尽管我承认这是一个相当令人吃惊的道具.

To clarify, I won't consider any answer that tells me std is special because I just used it as an example. I'm talking about a general issue, and I'm using std as a prop to illustrate it, though I do admit it's a rather startling prop.

推荐答案

未锚定命名空间的实际原因是通常一层命名空间就足够了.如果不是,通常会使用第二个级别来提供实现细节.最后,即使使用多个级别,它们仍然通常从根级别隐式指定.IE.即使在命名空间 ns1 中,您通常也会引用 ns1::ns2::foo 而不是 ns2::foo::ns1::ns2::foo.

The practical reason for unanchored namespaces is that one level of namespaces usually is enough. When it isn't, a second level is usually going to be used for implementation details. And finally, even when using multiple levels, they are still usually specified implicitly from root level. ie. even inside namespace ns1, you'd typically refer to ns1::ns2::foo instead of ns2::foo or ::ns1::ns2::foo.

因此,出于这三个原因,::ns1 形式在正常情况下是多余的.我会考虑的唯一情况是提交给 Boost,因为作为 Boost 作者,我不知道我的软件将在哪里使用.

So, for these three reasons the ::ns1 form is redundant in normal cases. The only case where I'd consider it would be in submissions to Boost, because as a Boost author I won't know where my software will be used.

相关文章