In p0896r4
23.7.11.1 Overview [range.split.overview]
- split_view takes a View and a delimiter, and splits the View into subranges on the delimiter. The delimiter can be a single element or a View of elements.
Example (with slight modification to compile)
#include <iostream>
#include <ranges>
#include <string>
int main()
{
std::string str{"the quick brown fox"};
std::ranges::split_view sentence{str, ' '};
for (auto word : sentence) {
for (char ch : word)
std::cout << ch;
std::cout << "*";
}
return 0;
}
Outputs:
the*quick*brown*fox*
However this is printing char by char, why can't I print a word instead?
for (auto word : sentence)
std::cout << word << std::endl;
Error: https://godbolt.org/z/GsPrhz
<source>:10:19: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'std::ranges::split_view<std::ranges::ref_view<std::__cxx11::basic_string<char> >, std::ranges::single_view<char> >::_OuterIter<true>::value_type')
Question: can I print the words? or does std::ranges::single_view<char>
pose a contraint ?
None of the standard views are printable, so the short answer is that you basically cannot. We're hoping to change this as part of P2214.
views::split
specifically has the issue that you can't even get a contiguous subrange out of it, so you can't meaningfully convert the pieces you get into string_view
s either. This is P2210.
The best solution I can offer today is to use the fmt
library, which lets you write:
char const* delim = "";
for (auto word : sentence) {
fmt::print("{}{}", delim, fmt::join(word, ""));
delim = " ";
}
I don't think fmt
has any support for joining ranges of ranges, so I did the delimiting manually.
Note that single_view<char>
is the pattern you're splitting on, not the piece you're getting back from split
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With