Разделение string_view с использованием диапазонов - PullRequest
3 голосов
/ 30 мая 2020

У меня есть строка, содержащая последовательность чисел, разделенных символом ,. Чтобы прочитать значения из последовательности в массив, я создал следующий код, который G CC 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();
}

Короче говоря, компилятор жалуется, что нет методов data() и size() доступно для типа переменной octet. Не понимаю ли я, что тип octet должен соответствовать критериям contiguous_range, как string_view? Судя по моему, это аргумент.

1 Ответ

3 голосов
/ 30 мая 2020

Не понимаю ли я, что тип octet должен соответствовать критериям contiguous_range, как string_view?

Да. octet равно не a contiguous_range. Внутренний диапазон split_view никогда не бывает сильнее, чем forward_range - это всегда только forward_range или input_range.

Это делает views::split чрезвычайно неудобным для использования для любого вида нетривиальный синтаксический анализ - именно потому, что, как вы демонстрируете в вопросе, вы не можете использовать такие вещи, как from_chars (или scanf или ...), если вы затем вручную не создадите из него непрерывный диапазон.

...