4
std::vector v{1,2,3};

for (auto&& t : v | view::sliding(2)) {
    auto&& [first, second] = t;  // error - t is a range
}

is there a similar view in range-v3 that can return a tuple?

something like sliding<2>

Adam
  • 1,724
  • 4
  • 21
  • 31

2 Answers2

4

You could zip together range with drop(range, i) for all i in [1,n) (DEMO):

std::vector v{1,2,3};

namespace view = ranges::view;
for (auto [first, second] : view::zip(v, view::drop(v, 1))) {
     std::cout << first << ", " << second << '\n';
}

This will quickly get ugly for larger n, and is almost certainly non-optimal, but far simpler than writing your own view adaptor.

Casey
  • 41,449
  • 7
  • 95
  • 125
  • 3
    For larger `n`, you can still use helper with `std::make_index_sequence` and `return ranges::view::zip(ranges::view::drop(v, Is)...);`. – Jarod42 Oct 04 '18 at 15:52
2

Assuming this is not exactly what you had in mind, but you can write something like:

template <typename T, size_t... I>
auto helper(T&& rng, std::index_sequence<I...>) {
   return std::make_tuple(rng[I]...);
}

int main() {
   std::vector v{1,2,3,4,5};
   for (auto&& t : v | ranges::view::sliding(3)) {
      auto&& [first, second, third] = helper(t, std::make_index_sequence<3>{});
      std::cout << first << ", " << second << ", " << third << std::endl;
    }
}

Otherwise, I don't know how to make compile-time-sized ranges.

Daniel Langr
  • 22,196
  • 3
  • 50
  • 93