【问题标题】:Why aren't C++14 standard-defined literals in the global namespace by default?为什么默认情况下全局命名空间中没有 C++14 标准定义的文字?
【发布时间】:2014-12-22 18:50:49
【问题描述】:

C++14 包括标准定义的文字,其中包括 std::string 和来自 <chrono> 标头的各种时间跨度。

要使用它们,您必须说 using namespace std::literals;(或一些变化,具体取决于您想要的文字,因为它们位于各种内联命名空间中)。

这一切都很好,但我很好奇为什么需要using 声明。没有前导下划线的 UDL 被保留用于实现,因此"hello world"s 在符合标准的程序中不可能有任何其他含义。

那么为什么#include <string> 不足以将文字转换功能带入作用域呢?为什么必须显式包含字面量命名空间?

编辑:N3531 是我能找到的最新版本的提案——不幸的是,它没有讨论将事物放入命名空间的动机,而只是说:

可以将[波特兰]讨论的要求总结如下:

  • 为(一组相关的)UDL 运算符使用内联命名空间

【问题讨论】:

  • 可能出于同样的原因,用户定义的文字必须以 _ 开头:forward compatibility。他们预计将来某个时候会添加更多文字,我想他们会将它们放在不同的命名空间中以避免命名冲突。
  • @Close voter:我非常怀疑这是基于意见的。标准委员会做出了决定。这是在问为什么他们做出了他们所做的决定。这不是基于意见。它基于委员会内部的历史讨论和决定,这是事实。
  • “没有前导下划线的 UDL 被保留用于实现”在哪里,在什么版本中?
  • 啊,[usrlit.suffix] 部分,至少从 n3485 草案开始就一直存在。所以不应该在需求之前编写任何代码。

标签: c++ c++14 user-defined-literals


【解决方案1】:

已经有两个名为 s 的 UDL:一个用于字符串,一个用于 seconds。由于后缀的名称可以理解的简洁,它们长期遭受名称冲突,因此将它们全部倒入一个命名空间不会长久。因此决定将它们放入内联命名空间中,允许明确的 (using namespace std::literals::chrono_literals) 和简单的 using 指令 (using namespace std)。

【讨论】:

  • 全局命名空间中永远不能有另一个 s 后缀,因为所有非标准 UDL 都必须以下划线开头。
  • @TristanBrindle ... 想象一下,为了这个论点,标准委员会本身想引入第二个operator"" s
  • @TristanBrindle:这里有三个利益相关者:标准、平台/实现/系统库和最终开发人员。只有最后一个被禁止使用不带下划线的 UDL 后缀。
  • 为了让您的示例更加真实,想象一下better_string 是否是string_view
  • @Cornstalks 引用的论文 N3531 实际上提到了string_view,并建议应该给它后缀sv
【解决方案2】:

标准库已经定义了s 的多个版本:

  1. 可用于定义字符串字面量。
  2. 可用于定义chrono::seconds 文字。

一种基于字符串文字,一种基于整数或double文字,当然,即它们实际上可以共存。但是,我预计将来s 可能会有更多用途。因此,必须选择导入哪些命名空间而不是强加于您似乎是一种合理的方法。

【讨论】:

    【解决方案3】:

    查看论文 N2765。 UDL 与常规名称查找过程挂钩。由于字符串文字具有常见的字符串类型,因此如果您忽略命名空间,则很有可能发生冲突。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-06
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 2015-05-28
      • 1970-01-01
      • 2021-07-14
      相关资源
      最近更新 更多