如何将std::string分割为std::string_view类型的Ranges v3范围?
如何将分割后的std::string片段转为std::string_view?
嘿,我来帮你搞定这个问题!你想把std::string按空格分割后得到std::string_view组成的范围,思路方向是对的,但直接用std::string_view构造函数去转换split出来的子范围行不通——因为ranges::view::split返回的是原字符串的字符子范围,不是直接的指针和长度,没法直接传给std::string_view的构造函数。
给你调整后的正确代码:
#include <string> #include <string_view> #include "range/v3/all.hpp" int main() { std::string s = "this should be split into string_views"; auto view = s | ranges::view::split(' ') // 把每个子范围转换成std::string_view | ranges::view::transform([](auto&& subrange) { // 获取子范围的起始指针:通过迭代器解引用取地址 const char* start = &*subrange.begin(); // 获取子范围的长度 std::size_t len = ranges::distance(subrange); return std::string_view(start, len); }); }
关键细节说明:
&*subrange.begin():subrange是原字符串的字符子范围,它的迭代器指向原std::string的内存区域,解引用后取地址就能得到字符的起始指针。如果你的环境支持C++20,推荐用ranges::to_address(subrange.begin())代替&*,更安全(避免迭代器是代理迭代器的情况)。ranges::distance(subrange):计算子范围的字符个数,作为std::string_view的长度。- 额外提醒:如果原字符串存在连续空格,
split会生成空的子范围,这时候可以加个过滤步骤去掉空的string_view:auto view = s | ranges::view::split(' ') | ranges::view::filter([](auto&& r) { return !ranges::empty(r); }) | ranges::view::transform([](auto&& subrange) { return std::string_view(ranges::to_address(subrange.begin()), ranges::distance(subrange)); });
最后别忘了:std::string_view是不持有内存的,所以原字符串s的生命周期必须比view长,否则会出现悬垂引用哦!
内容的提问来源于stack exchange,提问作者dani
相关产品推荐
相关产品推荐

