每个类都应该有自己的命名空间吗?

the*_*use 11 c++ coding-style namespaces

一段困扰我一段时间的事情:

目前的看法是,类型应保存在名称空间中,该名称空间仅包含属于该类型的非成员接口的函数(请参阅C++编码标准 Sutter和Alexandrescu或此处)以防止ADL引入不相关的定义.

这是否意味着所有类都必须具有自己的命名空间?如果我们假设将来可以通过添加非成员函数来扩充类,那么将两种类型放在同一名称空间中永远不会是安全的,因为其中一种类型可能会引入可能会干扰的非成员函数另一个.

我问的原因是命名空间对我来说变得很麻烦.我正在编写一个只有头文件库,我发现自己使用的是类名,例如project :: component :: class_name :: class_name.他们的实现调用辅助函数,但由于这些函数不能在同一个命名空间中,因此它们也必须完全合格!

编辑:

几个答案表明C++命名空间只是一种避免名称冲突的机制.事实并非如此.在C++函数中,使用Argument Dependent Lookup解析获取参数的函数.这意味着当编译器尝试查找与函数名称匹配的函数定义时,它将在查找候选项时查看与其参数的类型相同的名称空间中的每个函数.

这可能会产生意想不到的令人不快的后果,详见A Modest Proposal:Fixing ADL.Sutter和Alexandrescu的规则状态从不将函数放在与类相同的命名空间中,除非它是该类的接口的一部分.除非我准备给每个类都有自己的命名空间,否则我看不出我怎么能遵守这条规则.

更多建议非常欢迎!

Mic*_*yan 15

不,我从未听过那个会议.通常每个库都有自己的命名空间,如果该库有多个不同的模块(例如功能不同的不同逻辑单元),那么那些可能有自己的命名空间,尽管每个库有一个命名空间就足够了.在库或模块命名空间内,您可以使用命名空间detail或匿名命名空间来存储实现详细信息.每个类使用一个命名空间,恕我直言,完全矫枉过正.我肯定会回避这一点.同时,我强烈建议您至少为您的库创建一个名称空间,并将所有内容放在该名称空间或其子名称空间中,以避免与其他库发生名称冲突.

为了使其更具体,请允许我使用古老的Boost C++库作为示例.boost中的所有元素都位于boost::.Boost中有一些模块,例如具有自己的命名空间的进程间库boost::interprocess::,但在大多数情况下,boost的元素(特别是那些经常使用和跨模块的元素)只是驻留在boost::.如果你在boost中查看,它经常使用boost::detail或存储给定命名空间的实现细节.我建议你以这种方式为命名空间建模.boost::name_of_module::detail


小智 8

不,不,千倍不!C++中的命名空间不是架构或设计元素.它们只是一种防止名称冲突的机制.如果在实践中您没有名称冲突,则不需要名称空间.

  • "它们只是一种防止名字冲突的机制." 假.命名空间也用于指导ADL.无论如何,他们"为......"的重要性远不如他们实际*做的那么重要,如果在某些特定情况下他们所做的事情是不可取的. (4认同)
  • 命名空间正是*不是一个简单的命名机制!使用Argument Dependent Lookup(http://en.wikipedia.org/wiki/Argument_dependent_name_lookup),当使用类的对象时,与类相同的命名空间中的每个函数都被视为候选函数.因此Sutter和Alexandrescu的统治. (2认同)
  • @steve @thehouse命名空间是一种简单的冲突避免机制 - 如果你以这种方式设计你的软件. (2认同)
  • @Neil:是的,如果他们在没有完全限定的情况下调用该函数,则将参数传递给模板参数类型的对象,该对象碰巧是包含相同名称的无关函数的命名空间中的UDT,那么它可能赢得了'工作.因此,编写这些模板函数的人可能会低估其模板参数类型的要求.实际上没有一个选项可以忽略这个问题,并且好像它不会影响你,至少如果你正在编写库和可移植代码,并且想要正确地记录它们. (2认同)
  • 嗯,我已经知道编写的代码会被我从未见过的人调用,所以这是我想到的.许多用户会暗示许多名称空间.实际上我还没有发布过一个C++模板库,这就是为什么我处于"是的,我看到记录这个问题会有什么问题"的原因而不是"aha,我以前做过所有这些并且有答案.以下是我使用的规则......"或者"是的,我们都注定了,ADL完全像Sutter所说的那样被破坏了". (2认同)

Ben*_*igt 7

要避免ADL,您只需要两个名称空间:一个包含所有类,另一个包含所有松散功能.ADL绝对不是每个类都有自己的命名空间的好理由.

现在,如果您希望通过ADL找到某些函数,则可能需要为此目的创建名称空间.但是,为了避免ADL冲突,你实际上每个类实际上还需要一个单独的命名空间.