【问题标题】:Is there a specific reason nested namespace declarations are not allowed in C++?C++ 中不允许嵌套命名空间声明是否有特定原因?
【发布时间】:2011-04-05 22:20:59
【问题描述】:

标准不允许这样的代码:

namespace Hello::World {

//Things that are in namespace Hello::World

}

而是需要

namespace Hello { namespace World {

//Things that are in namespace Hello::World

}}

原因是什么?是当时根本没有想到,还是有特定的原因不包括在内?

似乎第一种语法更直接地表达了应该在哪个命名空间中,因为声明模仿了以后代码中命名空间的实际使用。如果您不幸使用“哑”括号计数缩进工具,它也会减少缩进。

【问题讨论】:

  • @AndreyT:我不是在问它是否合法,我知道它是非法的。我在问为什么这是非法的。
  • 投票“接近 - 不是真正的问题”的人缺乏阅读理解能力。这是一个具有客观答案且与编程相关的特定问题。
  • @Steve:实际上,我认为它更易于阅读是我希望看到这样一个功能的主要原因。
  • 啊哈!现在这个问题也是主观和争论的!现在,如果我们能让两个人投票结束,因为 off-topic过于本地化......

标签: c++ namespaces language-design rationale


【解决方案1】:

原因很可能是“因为这就是语言的演变方式。”

至少有一项提议("Nested Namespace Definition Proposal" 于 2003 年)允许嵌套命名空间定义,但未选择包含在 C++0x 中。

【讨论】:

  • 在查看了该提案并稍加思考之后,我认为您几乎可以肯定是对的。我敢打赌,它之所以没有被选中,只是因为提议的好处似乎不值得通过标准化流程获得提案的麻烦。
  • 接受投票数最高的答案,因为我显然无法在这里猜到真正的答案。
  • 作为参考,这个特性确实被 C++17 接受了。请参阅@Farway 下面的答案。
【解决方案2】:

嵌套命名空间定义是 C++17 工作草案的一部分。
该主题在提案中被提及作为此功能的示例,该功能是程序员的需求原始n4026 更新版本:n4230

当前最新草案:n4567(第 7.3.1 段第 10 项)

7.3.1 命名空间定义
...
10 带有封闭命名空间说明符 E、标识符 I 和命名空间主体 B 的嵌套命名空间定义等价于 namespace E { namespace I { B } }

例子

namespace A::B::C {
  int i;
}    The above has the same effect as:

namespace A {
  namespace B {
    namespace C {
      int i;
    }
  }
}

编译器支持

GCC 自version 6 启用使用-std=c++1z
Visual C++ 自 2015 update 3 启用使用 /std:c++latest
Clang 自 version 3.6 启用使用 -std=c++1z

【讨论】:

    【解决方案3】:

    我想你更希望它是这样的,给定namespace X::Y,它应该等同于“命名空间 X {命名空间 Y`。表面上听起来不错,但考虑一个极端情况:

    namespace Hello {
       namespace {
          namespace World {}
       }
    }
    
    // Does this refer to an existing namespace? Or does it define a new one?
    namespace Hello::World {}
    

    【讨论】:

    • +1 指出我什至不知道是合法的东西 :)
    • 那将是一个不同的命名空间。 namespace Hello::World { } 只是 namespace Hello { namespace World { } } 的简写,语言已经允许这样做。
    • @James - 所以基本上没有办法用嵌套语法引用匿名命名空间?这对我来说似乎是合理的,因为真的没有办法以任何其他方式直接引用匿名命名空间。
    • @Omnifarious:我想你可以使用namespace Hello::::World { },但我怀疑有人会支持:-P
    • @Potato:这是我为什么喜欢 C++ 的一个很好的例子。 :-O
    【解决方案4】:

    正如我在“可能重复”线程中所说,在 C++ 中,限定名称 保留用于引用先前声明的 实体。这适用于限定名称的“来源”:类和命名空间。

    【讨论】:

    • “完全重复”的意思是,“这个问题与另一个问题完全重复”,而不是“有一个适用于这两个问题的答案”。但是对此答案 +1。
    • 我认为这不足以解释它。您可以事先声明命名空间,但仍然不能使用此构造。
    • 那么,你赞成还是反对?我认为比利的意图是先前声明了命名空间……
    • @Potatoswatter:实际上,我不明白为什么这两种情况都会有所不同。
    【解决方案5】:

    我认为这是一种设计选择。

    第一个语法看起来不错。我也想拥有它。但是,第二个更结构化。您不会以这种方式创建嵌套命名空间:

    Hello::World::Everyone::Great {
    
    }
    

    你会提前声明吗?

    【讨论】:

    • 是的,我宁愿对软件组件进行更多分类。 Java 和 C# 等语言都允许这种语法,并且对它们来说工作得很好。它们都附带非常大的标准库,用于将事物分类到命名空间的层次结构使找到您要查找的组件变得更加容易。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多