std::string_view怎么能是constexpr?

How can std::string_view be constexpr?

提问人:JenyaKh 提问时间:10/25/2023 最后编辑:Jan SchultkeJenyaKh 更新时间:10/26/2023 访问量:229

问:

我试图在 SO 上找到答案,但失败了。对不起,如果这是重复的。然后我将结束这个问题。

您能解释一下两者之间的区别吗:

constexpr const char Str1[] = "qwerty";
constexpr auto Str1Size = sizeof(Str1) - 1;

constexpr std::string_view Str2{"qwerty"};
constexpr auto Str2Size = Str2.size();

我今天看到了第二个变体,但无法理解。AFAIU 是一个动态对象,因此内存将动态分配。那怎么会这样呢?std::string_viewconstexpr

此外,如果这些变体真的都可以,即是编译时的,那么它们有什么区别呢?AFAIK,不会有和结束它。全部吗?Str2'\0'

C++ C++17 constexpr 字符串视图

评论

7赞 Yksisarvinen 10/25/2023
std::string_view不分配任何内存。它只是一个视图,它存储指针和字符数。
1赞 Marek R 10/25/2023
std::string_view只是对字符串的 const 引用的花哨形式。如果是 const 引用字符串文字。costexpr
3赞 Raffallo 10/25/2023
“std::string_view 是一个动态对象,因此内存将被动态分配”,不,它不是。 将分配内存,但仅保存指向外部数据的指针std::stringstd::string_view
2赞 HolyBlackCat 10/25/2023
只有当它指向的字符串缺少它时,它才会缺少它。 实际上只是一个带有 a 的结构体。\0std::string_viewconst char *ptr; std::size_t size;
2赞 Swift - Friday Pie 10/25/2023
@JenyaKh,确实如此。 是 7 秒的数组,而不是 6 秒的数组。"qwerty"const char

答:

2赞 Jan Schultke 10/25/2023 #1

AFAIU 是一个动态对象,因此内存将动态分配。那怎么会这样呢?std::string_viewconstexpr

std::string_view不是动态分配的。它本质上是将字符数据和字符串长度组合成一个对象。这显然可以是.您可能会想到 ,它是动态分配的。const char*constexprstd::string

请注意,

constexpr const char* str = "qwerty";

...有效,因为不是动态分配的,而是静态存储持续时间。 指向此字符串文本。如果将其包装在 中,则指针将被复制。这些都不涉及动态分配。"qwerty"strstd::string_viewstr

此外,如果这些变体真的都可以,即是编译时的,那么它们有什么区别呢?AFAIK,不会有和结束它。全部吗?Str2'\0'

null 终止符是唯一显著的区别。 不保证以 null 结尾,因此在将字符数据包装在 . 也是一个标准的库容器,并且有一个更好的界面。您可以使用 等创建子字符串。std::string_viewstd::string_viewstd::string_view.substr


(1具体来说,null 终止符仍然包含在字符串数据中,可以使用 .data() 访问。但是,任意 std::string_view 可能不是以 null 结尾的,因此依赖它以 null 结尾是不安全的,并且容易出错。也没有安全的方法来检查 std::string_view 在运行时是否以 null 结尾,因此要么您(盲目地)相信它,要么假设它不是。

评论

2赞 Red.Wave 10/25/2023
但是您已经拥有可靠字符的数量。因此,如果您需要连接 C API,您可以使用带固定的 versions(' 而不是 ...)。所有 null 服务都是为了标记字符串的末尾,现在你用 .除非将 size 显式提供给 ctor,或者将 array(或 , ) 用作初始值设定项,否则 null 字符仍位于尾部。通过 wrapping/boxing ,您可以将其限制为 null 或非 null 终止字符串的任一类别。sizenstrndupstrdupsizestd::arraystd::vectorstring_view