std::string_view 文字是否保证以 null 终止?

问题描述 投票:0回答:1

我知道平凡的

std::string_view
不能保证以空终止。但是,我不知道
std::string_view
文字是否保证以空终止。

例如:

#include <string_view>

using namespace std::literals;

int main()
{
    auto my_sv = "hello"sv;
}

C++17 或更高版本是否保证

my_sv.data()
以空终止?

===以下已更新===

以下所有内容均来自n4820

  1. 根据 5.13.5.14,字符串文字以 null 结尾。
  2. 根据 5.13.8,用户定义的字符串文字由字符串文字加上自定义后缀组成。比如说,
    "hello"sv
    hello
    是字符串文字,
    sv
    是后缀。
  3. 根据 5.13.8.5,
    "hello"sv
    被视为
    operator "" sv(str, len);
    形式的调用,根据 5.13.5.14,
    str
    是 空终止。
  4. 根据 21.4.2.1,
    sv
    data()
    必须返回
    str

他们能否证明 C++ 标准保证

"hello"sv.data()
以空终止?

c++ string c++17 standards string-view
1个回答
37
投票

所以让我们把简单的部分排除掉。没有

string_view
永远是“NUL 终止的”,因为该对象代表一定大小的字符范围。即使您从 NUL 终止的字符序列创建
string_view
string_view
本身 仍然不是“NUL 终止”。

您真正要问的问题是:实现是否有一些余地来使语句

"some literal"sv
产生一个
string_view
,其
data
成员指向由
"some literal"表示的以NUL结尾的字符串文字
?也就是说,是这样的:

string_view s = "some literal"sv;

允许以与此不同的任何方式行事:

const char *lit = "some literal";
string_view s(lit, <number of chars in of lit>);

在后一种情况下,

s.data()
保证是指向字符串文字的指针,因此您可以将该指针视为指向以 NUL 结尾的字符串的指针。您在问前者是否同样有效。

让我们调查一下。 operator""sv

 重载的 
定义为 :

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 实现并因此从它将为作为
str
传递的字符串文字创建的数组中删除 NUL 字符是否合法?

让我们看看字符串的 UDL 是如何工作的

如果

L
是用户定义的字符串文字,则令
str
为不带 ud 后缀文字,并令
len
str
中的代码单元数(即其长度 )排除终止空字符)。文字
L
被视为对以下形式的调用

operator "" X(str, len)

注意我强调的短语。我们知道“没有 ud 后缀的文字”的行为。第二个短语特别提到了

str
的预期 NUL 终止符。我想说这是一个非常明确的声明,
str
将被赋予一个文字字符串。该文字字符串将按照 C++ 中的常规字符串文字规则构建,因此将以 NUL 结尾。

鉴于上述情况,我认为可以肯定地说,这里的实施没有回旋余地。 UDL 返回的

string_view
must 指向由 UDL 中指定的字符串文字定义的数组,并且与任何其他字符串文字一样,该数组will 以 NUL 结尾。

话虽如此,回顾我的第一段。您不应编写任何假设

string_view
以 NUL 结尾的代码。即使
string_view
的创建者和它的消费者彼此相邻,我也会将其称为代码味道。

© www.soinside.com 2019 - 2024. All rights reserved.