C++ 中未命名命名空间的使用

Posted

技术标签:

【中文标题】C++ 中未命名命名空间的使用【英文标题】:Uses of unnamed namespace in C++ 【发布时间】:2011-07-15 19:04:54 【问题描述】:

什么时候会在 C++ 中使用未命名的命名空间?从某种意义上说,它比独立功能更好吗?另外,它应该只用在源文件中而不用在头文件中吗?

【问题讨论】:

另请参阅此主题:Superiority of unnamed namespace over static ? 【参考方案1】:

它用于隐藏名称。每个未命名的命名空间都是唯一的。链接here 进行了更详细的说明。它通常在源文件中用于隐藏应该只有内部链接的函数(例如,不暴露给外界)。

【讨论】:

链接失效【参考方案2】:

未命名的命名空间是全局静态变量和函数的“C++ 版本”。请注意,您也可以为类使用未命名的命名空间。

【讨论】:

【参考方案3】:

根据 Stroustrup 的说法,您应该在旧 C 语言中您会使用 static 全局变量的地方使用它。这个想法是,有问题的项目对于它们所在的源文件可以是“全局的”,但不会污染编译中任何其他源文件的命名空间。

换句话说,您不应该在 C++ 中创建 static 全局变量。您应该改用未命名的命名空间。

我发现在一些情况下它们在头文件中很有用,但这种情况应该很少见。大多数情况下,我认为是为了声明可抛出的异常。在这种情况下,所讨论的定义对于#includes 该标头的所有内容都是全局的,但对于没有的内容则不是。

【讨论】:

static 在最新一期的 FCD (n3225) 中不再标记为已弃用。委员会认识到它对于单个函数或全局函数来说不那么冗长。 “grep”也更容易,因为它出现在声明附近,并且不需要解析器。 @Matthieu:但是这些函数具有内部链接。未命名的命名空间被称为“高级”的真正原因是它们“隐藏”了符号,而不是更改对象/函数的链接,这更接近人们在使用它时通常想要实现的目标。这在 C++0x 中并没有改变,他们已经认识到 (1) 如果您担心外部链接会很昂贵,那么您需要内部链接,这反过来意味着您需要 static,并且 (2) 他们'由于 C 兼容性,在这种情况下永远不会删除 static,所以弃用它是一个空洞的威胁。 @Steve:我期待它也会改变链接,如果没有人知道这个符号,那么在外部维护它的目的是什么? @Matthieu:在 C++03 中,将其用作模板参数是合法的。我认为 C++0x 使得在模板中使用内部链接的东西是合法的,我可能是错的。不过,我有点忘记了我们应该谈论的是函数还是对象…… @SteveJessop:如果您担心外部链接会很昂贵,那么您需要内部链接,这反过来意味着您需要静态使用 C++11(§3.5/ 4) 未命名的命名空间似乎有像static 这样的内部链接。【参考方案4】:

未命名的命名空间对翻译单元是私有的,这可以用来屏蔽在不同翻译单元中出现的同名全局变量和函数,从而不会出现链接冲突。

例如,您需要一个仅在 .cpp 文件中定义并仅在该文件中使用的类。你想叫它CModuleLock。如果它不在未命名的命名空间中,并且其他一些 .cpp 文件意外有另一个类 CModuleLock 不在未命名的命名空间中,您将无法链接您的程序。

【讨论】:

我有时会为可能是私有内部类的类使用未命名的命名空间,但我想在相似的类之间共享(可能是那些实现相同概念的类)。当然,如果类变得足够通用,我会将其移动到命名空间

以上是关于C++ 中未命名命名空间的使用的主要内容,如果未能解决你的问题,请参考以下文章

JAXB:为啥在生成的 xml 文档中未使用定义的命名空间前缀?

一次删除整个项目或解决方案中未使用的命名空间

C++问题:关于匿名命名空间

命名空间的使用方式(c++基础语法一)

C++命名空间详解

C++ 命名空间 (namespace)