Reputation: 863
I have a string containing a sequence of numbers separated with the ,
character. To read values from the sequence into an array I created the following code the GCC 10 refuses to compile:
#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();
}
Briefly speaking the compiler complains that there are no data()
and size()
methods available for the type of the octet
variable. Do I misunderstand that type of octet
should meet the contiguous_range
criteria as the string_view
does? It seems to be argumentative from my POV.
Upvotes: 4
Views: 1979
Reputation: 302757
After the adoption of P2210 as a defect report against C++20, views::split
can now preserve contiguity, so the above code is now valid and compiles on gcc trunk.
Do I misunderstand that type of
octet
should meet thecontiguous_range
criteria as thestring_view
does?
Yes. octet
is not a contiguous_range
. The inner range of a split_view
is never stronger than a forward_range
- it is only ever a forward_range
or an input_range
.
This makes views::split
exceedingly awkward to use for any kind of non-trivial parsing - precisely because, as you demonstrate in the question, you can't use things like from_chars
(or scanf
or ... ) unless you then manually produce a contiguous range out of it.
Upvotes: 4