Why cant I chain after std::ranges::views::join?
Asked Answered
B

1

6

I recently discovered the ranges stdandard library and encountered a strange behavior. When chaining multiple range adaptors, I can't chain after using std::ranges::views::join:

vec | std::ranges::views::slide(2) | std::ranges::views::join

works as intended, but

vec | std::ranges::views::slide(2) | std::ranges::views::join | std::ranges::views::slide(2)

will result in compilation error:

error: no match for 'operator|' (operand types are 'std::ranges::join_view<std::ranges::slide_view<std::ranges::ref_view<std::vector<int> > > >' and 'std::ranges::views::__adaptor::_Partial<std::ranges::views::_Slide, int>')
  265 |   vec | std::ranges::views::slide(2) | std::ranges::views::join | std::ranges::views::slide(2);
      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                      |                                                     |
      |                                      |                                                     std::ranges::views::__adaptor::_Partial<std::ranges::views::_Slide, int>
      |                                      std::ranges::join_view<std::ranges::slide_view<std::ranges::ref_view<std::vector<int> > > >

Why is that? and what do I have to do to make multiple joins work?

Thanks in advance!

Berar answered 9/3 at 15:5 Comment(2)
A minimal reproducible example would be useful. I was able to get having two slides work, but I had to use an interim value. Probably a better way. But I had to guess what your omitted code is doing.Assuasive
FYI, std::ranges::views::meow can be simply written as std::views::meow. std::views is a namespace alias for std::ranges::views.Britney
A
6

slide_view requires forward_range since the elements need to be traversed more than once.

This is not the case for join_view in your case, because the latter joins a nested range whose elements are prvalue ranges (slide_view acts on vector will produce a range whose element type is prvalue span as "window"), which makes it just an input_range.

The constraints are not satisfied so compilation fails.

Anergy answered 9/3 at 15:47 Comment(1)
Thanks a lot! To make it a forward_range I can do the following: vec | std::ranges::views::slide(2) | std::ranges::views::join | std::ranges::to<std::vector<int>>() | std::ranges::views::slide(2). Or is there a better way?Berar

© 2022 - 2024 — McMap. All rights reserved.