17

I need to split a std::string at all spaces. The resulting range should however transform it's element to std::string_views. I'm struggling with the "element type" of the range. I guess, the type is something like a c_str. How can I transform the "split"-part into string_views?

#include <string>
#include <string_view>
#include "range/v3/all.hpp"

int main()
{
    std::string s = "this should be split into string_views";

    auto view = s 
            | ranges::view::split(' ') 
            | ranges::view::transform(std::string_view);
}
dani
  • 3,677
  • 4
  • 26
  • 60

1 Answers1

28

(One of) the problem here is that ranges::view::split returns a range of ranges, and you cannot construct a std::string_view directly from a range.

You want something like this:

auto view = s
    | ranges::views::split(' ')
    | ranges::views::transform([](auto &&rng) {
            return std::string_view(&*rng.begin(), ranges::distance(rng));
});

There might be a better/easier way to do this but:

  • &*rng.begin() will give you the address of the first character of the chunk in the original string.
  • ranges::distance(rng) will give you the number of characters in this chunk. Note that this is slower than ranges::size but required here because we cannot retrieve the size of rng in constant time.
Holt
  • 36,600
  • 7
  • 92
  • 139
  • Final `view` is probably `string_view` of single elements – P0W Jan 23 '18 at 13:49
  • 1
    @P0W No! `split` does not "return" a range of character, it returns a range **of range**, so each `rng` is itself a range of character corresponding to a word inside `s` (a pair of iterators to `s`), which is why I can construct a `std::string_view` from it. – Holt Jan 23 '18 at 13:50
  • 6
    Thanks for the [P1989R2](http://open-std.org/JTC1/SC22/WG21/docs/papers/2021/p1989r2.pdf) and [P2210R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2210r2.html), the `return std::string_view(&*rng.begin(), ranges::distance(rng));` can be simplify into `return std::string_view(r);`. – 康桓瑋 Jun 22 '21 at 17:01