因此,让我们把简单的部分排除掉。不string_view
永远是“NUL 终止”,因为该对象代表一定大小的字符范围。即使您创建了一个string_view
从 NUL 终止的字符序列中,string_view
itself仍然不是“NULL 终止”。
您真正要问的问题是:实现是否有一些余地来发表声明"some literal"sv
产量astring_view
whose data
member does not指向由 NUL 结尾的字符串文字"some literal"
?也就是说,是这样的:
string_view s = "some literal"sv;
允许行为any way与此不同:
const char *lit = "some literal";
string_view s(lit, <number of chars in of lit>);
在后一种情况下,s.data()
保证是指向字符串文字的指针,因此您可以将该指针视为指向以 NUL 结尾的字符串的指针。您问的是前者是否同样有效。
我们来调查一下。这的定义operator""sv过载被规定为 https://timsong-cpp.github.io/cppwp/n4659/string.view.literals:
constexpr string_view operator""sv(const char* str, size_t len) noexcept;
返回:string_view{str, len}
.
这是该函数行为的标准规范:它返回一个string_view
它指向由提供的内存str
。因此,实现不能分配一些隐藏内存并使用它或其他什么;返回的string_view::data
是必须的返回相同的指针str
.
现在,这给我们带来了一个不同的问题:是str
required是一个以 NUL 结尾的字符串?也就是说,编译器看到您正在使用sv
UDL 实现,因此从它将为传递的字符串文字创建的数组中删除 NUL 字符str
?
让我们看看字符串的 UDL 如何工作 https://timsong-cpp.github.io/cppwp/n4659/lex.ext#5:
If L
是一个用户定义的字符串文字,让str
be the 不带 ud 后缀的文字然后让len
是代码单元的数量str
(即它的长度排除终止空字符)。字面意思L
被视为以下形式的调用
operator "" X(str, len)
请注意我强调的短语。我们知道“没有 ud 后缀的文字”的行为。第二个短语特别提到了预期的 NUL 终止符str
。我想说这是一个非常明确的声明str
将给出一个文字字符串。该文字字符串将按照 C++ 中的常规字符串文字规则构建,因此将以 NUL 结尾。
鉴于上述情况,我认为可以肯定地说,这里的实施没有回旋余地。这string_view
由 UDL 返回must指向由 UDL 中指定的字符串文字定义的数组,并且与任何其他字符串文字一样,该数组will以 NULL 终止。
话虽如此,please回顾我的第一段。您不应该编写任何假设的代码string_view
以 NUL 结尾。我会把它称为代码味道,即使它的创建者string_view
并且消费者彼此相邻。