std::string_view字面值保证以空字符结尾吗?

24

我知道普通的 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()是以null结尾的?

=== 下面已更新 ===

以下内容均来自n4820:

  1. 根据5.13.5.14,字符串字面值以null结尾。
  2. 根据5.13.8,用户定义的字符串字面值由一个字符串字面值和一个自定义后缀组成。比如说,"hello"svhello是字符串字面值,sv是后缀。
  3. 根据5.13.8.5,"hello"sv被视为一个形式为operator "" sv(str, len);的调用;根据5.13.5.14,str是以null结尾的。
  4. 根据21.4.2.1,svdata()必须返回str

他们能证明C++标准保证"hello"sv.data()是以null结尾的吗?


2
在这个网站上,使用绿色复选标记来表示“已解决”的答案;缺少此类复选标记表示“未解决”。您不应该在标题中写入“已解决”等字样。 - M.M
string_view 是一个类。类不是以 null 结尾的。如果能解释清楚你所询问的内容(例如给出一个使用 string_view 的代码示例,展示你所询问的情况),那么问题会更加明确。 - M.M
@M.M,OP的问题不是很清楚吗?您认为像这些一样添加几行代码会有益处吗? - Bob__
@M.M 所以问题可以重新表述为:“在使用 auto my_sv = "hello"sv; 的情况下,C++17或更高版本是否保证 my_sv.data() 是以空字符结尾的?” - Bob__
我真正的意思是,data() 函数是否会返回一个以 null 结尾的 C 字符串。 - xmllmx
显示剩余5条评论
1个回答

31

让我们先来说说简单的部分。任何一个 string_view 都不会是“NUL-terminated”(以对象代表字符的大小范围为意义),即使你从以 NUL 结尾的字符序列创建了一个 string_viewstring_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的创建者和其用户彼此紧密相连,我也认为这是一种代码气味。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接