让我们先来说说简单的部分。任何一个 string_view
都不会是“NUL-terminated”(以对象代表字符的大小范围为意义),即使你从以 NUL 结尾的字符序列创建了一个 string_view
,string_view
本身仍然不是“NUL-terminated”。
你真正想问的问题是:实现是否有一些余地,使语句 "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;
返回结果为:
该函数的标准规范是返回一个指向由str
提供的内存的string_view
。因此,实现不能分配一些隐藏的内存并使用它或其他任何东西;返回的string_view::data
需要返回与str
相同的指针。
现在,这引出了另一个问题:是否需要str
是以NUL结尾的字符串?也就是说,编译器是否有权将NUL字符从它将为传递给str
的字符串字面量创建的数组中删除,当它看到您正在使用sv
UDL实现时?
让我们看看如何使用UDLs来处理字符串:
如果L
是用户定义的字符串字面量,则将str
设置为不带其ud后缀的文字,将len
设置为str
中的代码单位数(即其长度,但要排除终止空字符)。将字面量L
视为调用形式
operator "" X(str, len)
请注意我强调的短语。我们知道“没有其ud后缀的文字”的行为。第二个短语明确提到了str
期望的NUL终止符。我认为这是一个非常明确的陈述,即str
将被赋予一个字面字符串。而且该字面字符串将根据C++中的常规字符串字面规则构建,因此将以NUL结尾。
鉴于上述情况,我认为在这里的实现中没有任何余地。由UDL返回的string_view
必须指向在UDL中指定的字符串字面定义的数组,并且像任何其他字符串字面一样,该数组将以NUL结尾。
话虽如此,请检查我的第一段。您不应编写假定string_view
以NUL结尾的任何代码。即使string_view
的创建者和其用户彼此紧密相连,我也认为这是一种代码气味。
string_view
是一个类。类不是以 null 结尾的。如果能解释清楚你所询问的内容(例如给出一个使用string_view
的代码示例,展示你所询问的情况),那么问题会更加明确。 - M.Mauto my_sv = "hello"sv;
的情况下,C++17或更高版本是否保证my_sv.data()
是以空字符结尾的?” - Bob__