为什么标准库的一部分位于单独的命名空间

时间:2018-01-18 15:04:39

标签: c++

为什么C ++标准库的某些部分(似乎在更新的标准中似乎越来越常见)不是直接在::std命名空间中,而是在嵌套的命名空间中?我想到了std::chronostd::filesystem两个例子。

3 个答案:

答案 0 :(得分:9)

显而易见的原因与任何其他项目相同:没有它就会发生名称冲突。例如,std::filesystem::copystd::copy

这不是一个完整的解释,因为

  • 我无法立即在std::chrono命名空间
  • 中看到任何冲突
  • 委员会可以选择一个非冲突的名称

更令人信服,

  1. 这些库基于他们的Boost前辈,因为这些库已被证明是有用的并且经过了充分测试。这意味着现有代码使用它们,如果命名空间结构没有改变,并且没有引入新的冲突,那么将代码移植到C ++ 11版本会更容易。
  2. 更广泛地说,自标准库的第一个版本以来,C ++最佳实践已经发展。
  3. 请注意(正如默认在注释中指出的),正则表达式库选择与Boost over namespace最佳实践的一致性,因此看起来#1更重要。 std::thread等也是如此。

    将事实与推测和假设区分开来:

    • 讨论的库基于Boost前辈
    • 讨论过的库保留了Boost前辈的名称空间结构
    • 讨论过的库的命名空间结构彼此之间(或与标准库的其余部分)不一致
    • 即使没有名称冲突,更改C ++中的命名空间结构也会产生与ADL相关的副作用(因此它不是一个简单的搜索和替换)

    结论:选择名称空间结构是为了与Boost保持一致,而不是与标准库的其余部分保持一致,甚至是在C ++ 11中添加的库中。

答案 1 :(得分:0)

拥有多个名称空间可以最大限度地减少别名问题的可能性。标准库中的所有内容都必须在std::范围内,但是标准库对于单个命名空间来说仍然非常大。例如,在std::filesystem中,您有std::filesystem::status函数。很容易想象库的其他部分在某些时候可能需要status函数。在读取代码时,命名空间也使函数的目的或“域”更加清晰。

此外,例如,如果您在代码中的某个位置using namespace std;,您可能会在当前命名空间中自己拥有一些status功能,这样可以避免重复{{1}无需将标准库中的所有内容直接拖到本地命名空间中,或者更有选择地选择要引入的特定名称子集。

也就是说,将API分解为不可命名的命名空间也不太实际。也许更熟悉C ++标准化过程的人可以提供更完整的答案,详细说明委员会如何决定何时添加命名空间,但最终是设计和风格问题,并且没有明确的,不容置疑的规则。

答案 2 :(得分:0)

考虑std::filesystem::absolute

如果没有filesystem子名称空间,则此函数应该被命名为std::filesystem_absolute。这是可行的方法,但不如具有子名称空间的方法灵活。请记住,您可以使用Namespace aliases

  

似乎在更近期的标准中它变得越来越普遍

我认为情况就是这样,因为标准库变得越来越大。