使用范围拆分string_view

Splitting a string_view using ranges

本文关键字:view string 拆分 使用范围      更新时间:2023-10-16

我有一个字符串,其中包含用,字符分隔的数字序列。为了将序列中的值读取到数组中,我创建了GCC 10拒绝编译的以下代码:

#include <ranges>
#include <string_view>
#include <charconv>
#include <array>
template<std::size_t Sz>
bool to_bytes(std::array<std::uint8_t, Sz> &data, std::string_view string) {
auto target = data.rbegin();
for (const auto octet : string | std::views::split('.')) {
if (target == data.rend()) {
return false;
}
const auto octet_begin = octet.data();
const auto octet_end = octet_begin + octet.size();
const auto error = std::error_code(std::from_chars(octet_begin, octet_end, *target).ec);
if (error) {
return false;
}
++target;
}
return target == data.rend();
}

简而言之,编译器抱怨没有可用于octet变量类型的data()size()方法。我是否误解了octet类型应该像string_view一样符合contiguous_range标准?从我的 POV 来看,这似乎是争论的。

在采用 P2210 作为针对 C++20 的缺陷报告后,views::split现在可以保持连续性,因此上述代码现在有效并在 gcc 主干上编译。


我是否误解了octet类型应该像string_view一样符合contiguous_range标准?

是的。octet不是contiguous_range.split_view的内部范围永远不会比forward_range强——它只是一个forward_range或一个input_range

这使得views::split用于任何类型的非平凡解析都非常尴尬 - 正是因为,正如您在问题中演示的那样,您不能使用from_chars(或scanf或...(之类的东西,除非您手动生成一个连续的范围。