【问题标题】:User-Defined String Literals Vs. Other User-Defined Literals用户定义的字符串文字与。其他用户定义的文字
【发布时间】:2012-10-18 05:18:10
【问题描述】:

让我们考虑以下来自 C++11 标准的引用(准确地说是the N3376 draft):

(2.14.8.5)

如果 L 是用户定义的字符串文字,则令 str 为不带文字的文字 它的 ud-suffix 并让 len 是 str 中的代码单元数(即,它的 长度不包括终止空字符)。文字 L 是 被视为表单的调用

     operator "" X (str , len )

而对于所有其他类型的用户定义文字(浮点、整数、字符),即使文字本身作为字符串传递,长度也永远不会传递。例如:

42_zzz; // calls operator "" _zzz("42") and not operator "" _zzz("42", 2)

为什么字符串和非字符串用户定义的文字有这种区别?或者我应该说,为什么实现为 UD 字符串文字传递 len?与其他文字的情况一样,长度可以通过空终止来推断。我错过了什么?

【问题讨论】:

  • 可能与编码/字符集有关。在此之前的其他段落都有“[注意:序列 c1c2 ...ck 只能包含来自基本源字符集的字符。- end note ]”。
  • @Mat:但是其他编码或字符集的字符串仍然是空终止的,不是吗?
  • 空终止是不够的。我猜“基本源字符集”不包括\0

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


【解决方案1】:

对于字符串文字,可以合理地想象空字符嵌入字符串序列中,例如"a\0b"。为了允许实现使用整个字符串文字,即使有嵌入的空字符,它也需要知道文字的长度。用户定义文字的其他形式不能包含嵌入的零字符。

【讨论】:

  • 顺便说一句,即使在 C99 中也可以定义一个宏,当使用标识符和字符串字面量调用该宏时,将创建一个编译时常量结构,该名称包含字符串的长度,后跟一个包含字符串的文本,但不是尾随的 null(不确定它是否可以在 C11 下编译干净)。不确定 C++ 中的用户定义字符串文字类型是否可以实现这样的事情,但如果可以的话,它看起来很方便。
  • @supercat:我不反对您可以确定字符串文字的长度。但是,如果您只传递了char const*,则无法确定字符串文字的长度!通过查找空字符来确定大小的常规方法仅确定字符串的大小,直到第一个空字符。不知何故需要字符串文字的大小(这也是您描述的宏也取决于:它只是使用sizeof(literal)-1 来确定文字中的字符数(不包括结尾的\0)。
  • 当然需要字符串的大小,这就是为什么我提到的结构将它放在字符串之前;我的观点是,即使在 C 宏中,也可以将文字字符串的长度用作整数常量。顺便说一句,我的代码使用了不同的宏,它们根据字符串是 0-63 字节、0-2047 还是 0-16777215 [使用 1、2 或 4 字节前缀]生成不同的结构。还有一些宏可以用一、二和四字节前缀初始化边界检查字符串缓冲区。字符串处理方法自动检测前缀类型,也可以...
  • ...处理一个特殊的“间接标志”前缀字节,后跟一个描述字符串的结构。想要将整个字符串传递给方法的代码可以传递直接指针;想要传递一部分的代码可以创建一个描述该部分的结构并传递一个指向该部分的指针。安全的边界检查字符串处理,无需手动跟踪字符串长度。
【解决方案2】:

字符串在 C/C++ 中总是以 null 结尾,但这绝不意味着它们不能包含嵌入的 \0 字符,您可能有 "1234\05678" 并且虽然此字符串以 null 结尾,但它包含一个额外的 '\0`在里面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    • 2015-04-22
    相关资源
    最近更新 更多