Consider this code snippet (adapted from cppreference.com):
constexpr std::string_view text{"Hello-+-C++-+-23-+-!"};
constexpr std::string_view delim{"-+-"};
std::ranges::for_each(text | std::views::lazy_split(delim), act_on_substring);
I want to do the same for a stream - say, std::cin
- instead of text
. I've tried:
auto isv = std::views::istream<std::string>(std::cin);
constexpr std::string_view delim{"-+-"};
std::ranges::for_each(isv | std::views::lazy_split(delim), act_on_substring);
But this code fails to compile:
<source>:21:31: error: invalid operands to binary expression ('basic_istream_view<basic_string<char, char_traits<char>, allocator<char>>, char, char_traits<char>>' and '_Partial<_LazySplit, decay_t<const basic_string_view<char, char_traits<char>> &>>' (aka '_Partial<std::ranges::views::_LazySplit, std::basic_string_view<char, std::char_traits<char>>>'))
21 | std::ranges::for_each(isv | std::views::lazy_split(delim), act_on_substring);
| ~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
why?
Although views::lazy_split
supports input_range
, since the latter is a single-pass range, there is no way to go back to the previous element once iterated. In this case, the pattern range must be a tiny-range
, which means its size must be smaller than or equal to 1.
The most you can do is:
std::ranges::for_each(
std::views::istream<char>(std::cin) | std::views::lazy_split('+'),
act_on_substring
);