提问人:Yves 提问时间:6/26/2023 最后编辑:DeduplicatorYves 更新时间:6/26/2023 访问量:347
我可以更改已分配给 std::string_view 的 std::string 吗?
Can I change a std::string, which has been assigned to a std::string_view
问:
我只知道 C++17 引入了 .它不包含任何字符串,而是指向一个字符串。如果是这样,我对下面的情况感到困惑:std::string_view
std::string str = "abc";
std::string_view strV = str;
std::cout << strV << std::endl;
str = "1";
std::cout << strV << std::endl;
我刚刚在一些 c++17 编译器上在线尝试了这段代码,这是输出:
abc
1c
显然,这不是我所期望的。1c
那么这是否意味着我们不应该更改已分配给 a 的字符串?std::string_view
答:
string_view存储指向字符串开头和字符串长度的指针。 替换字符串存储的文本会使它们都无效,因为这可能会导致不同的长度和/或不同的存储位置。
所以,是的,更改字符串会使string_view无效。
评论
一般来说,你不应该,因为它很脆弱。
无论如何:
您可以更改引用背后的数据(a 是对字符串段的引用,而不是对字符串的引用,由 start 和 length 组成),只需注意您所做的以及您是如何做到的。
虽然不要取消分配它,但使用悬空引用是不好的。std::string_view
std::string
std::string
如果新值适合当前容量,并且没有移动分配,或者两者都处于 SBO 模式,则不会重新分配。
在您的示例中,这三个都为真。
唯一的问题是,字符串终止符之外的数据在赋值后是不确定的,尽管它没有被显式覆盖,因此为了提高效率而保留。c
评论
str = "1"
str = something_that_returns_a_string()
str = another_str
str[1] = '1'
std::string_view
只是对包含字符的缓冲区的 const 引用的花哨形式。此缓冲区可以由 管理,也可以是字符串文本或 的某个数组。std::string
char
因此,使用不得超出此缓冲区的生存期。在您的示例中,缓冲区在使用字符串视图之前被修改,导致未定义的行为。std::string_view
现在,由于大多数编译器都在实现小字符串优化,因此您的示例不会崩溃。在更一般的情况下,此代码将惨遭失败。
请注意,引入这主要是为了更有效地解析未修改的长字符串中的一些数据。std::string_view
评论
std::string_view