xml*_*lmx 9 c++ string standards string-view c++17
我知道,琐碎小事std::string_view不能保证会以null结尾。但是,我不知道std::string_view文字是否保证为空终止。
例如:
#include <string_view>
using namespace std::literals;
int main()
{
auto my_sv = "hello"sv;
}
Run Code Online (Sandbox Code Playgroud)
C ++ 17或更高版本是否保证以my_sv.data()Null结尾?
===以下为更新===
以下全部来自n4820:
- 根据5.13.5.14,字符串文字是空终止的。
- 根据5.13.8,用户定义的字符串字面量由字符串文字和自定义后缀组成。说,
"hello"sv,hello是字符串文字,sv是后缀。- 按照5.13.8.5,
"hello"sv作为表单的一个呼叫被处理operator "" sv(str, len);为每5.13.5.14,str是空终止。- 按照21.4.2.1,
sv的data()必须返回str。
他们可以证明"hello"sv.data()C ++标准保证它可以为空终止吗?
因此,让我们将简单的部分排除在外。否string_view是有史以来“NUL封端”,在对象表示字符的大小的范围的意思。即使您string_view从NUL终止的字符序列创建一个,其string_view 本身仍不是“ NUL终止”。
您真正要问的问题是:实现是否有一些余地使语句"some literal"sv产生string_view其data成员未指向以NUL终止的字符串文字表示的"some literal"?即是这样的:
string_view s = "some literal"sv;
Run Code Online (Sandbox Code Playgroud)
在允许的行为任何方式从这个是不同的:
const char *lit = "some literal";
string_view s(lit, <number of chars in of lit>);
Run Code Online (Sandbox Code Playgroud)
在后一种情况下,s.data()保证是指向字符串文字的指针,因此您可以将该指针视为指向以NUL结尾的字符串的指针。您在问前者是否同样有效。
让我们调查一下。过载的定义为operator""sv:
Run Code Online (Sandbox Code Playgroud)constexpr string_view operator""sv(const char* str, size_t len) noexcept;返回:
string_view{str, len}。
这是此函数的行为的标准规范:它返回一个string_view,该指针指向所提供的内存str。因此,实现无法分配一些隐藏内存并使用该内存或其他任何内存;返回string_view::data 值必须返回与相同的指针str。
现在,这给我们带来了一个不同的问题:是否str 要求是NUL终止的字符串?也就是说,对于编译器来说,如果看到您正在使用svUDL实现并因此从要为传递为的字符串文字创建的数组中删除NUL字符,是否合法str?
让我们看一下字符串的UDL如何工作:
如果
L是用户定义的,字串文本,让str是没有其UD-后缀文字和让len是代码单元的数量str(即,其长度不包括终止空字符)。文字L被视为形式的调用Run Code Online (Sandbox Code Playgroud)operator "" X(str, len)
注意我强调的短语。我们知道“没有ud后缀的文字”的行为。第二个短语特别提到了预期的NUL终止子str。我会说这是一个非常明确的声明,str将给出一个文字字符串。该文字字符串将按照C ++中的常规字符串文字规则构建,因此将以NUL终止。
鉴于以上所述,我认为可以肯定地说这里没有实现的余地。在string_view由UDL返回必须指向由在UDL中指定的字符串文字定义的阵列,并且像任何其他字符串文字,该阵列将是NUL结尾。
话虽如此,请回顾我的第一段。您不应编写任何假定a string_view为NUL终止的代码。即使string_viewand 的创建者彼此相邻,我也将其称为代码气味。