0

I don't understand why the following code does not compile while the commented out version does work.

#include <range/v3/all.hpp>
#include <iostream>

namespace rv = ranges::views;

int main() {

    //std::vector<int> fives = {5,5,5,5,5,5,5,5,5,5};
    //auto rng = fives | rv::sliding(2);

    auto lazy_fives = rv::generate( [](){ return 5;});
    auto rng = lazy_fives  | rv::sliding(2);

    for (auto pair : rng | rv::take(10)) {
        for (auto val : pair) {
            std::cout << val << " ";
        }
        std::cout << "\n";
    }
}

On godbolt here.

jwezorek
  • 8,592
  • 1
  • 29
  • 46

1 Answers1

0

As @康桓瑋 says in comments, the issue is that sliding_view requires a forward_range, but generate yields an input_range.

A workaround is either to dump the generated range to a vector and create a sliding view of that, or I believe it is possible to use one's own generate written on top of iota like so

#include <range/v3/all.hpp>
#include <iostream>

namespace rv = ranges::views;

template<typename F>
auto generate_forward_range(F func) {
    return rv::iota(0) | rv::transform( [func](int n){ return func();});
}

int main() {

    auto lazy_fives = generate_forward_range( [](){ return 5;} );
    auto rng = lazy_fives | rv::sliding(2);

    for (auto pair : rng | rv::take(10)) {
        for (auto val : pair) {
            std::cout << val << " ";
        }
        std::cout << "\n";
    }

}

On godbolt here. I assume this works because iota generates a forward_range leading to transform yielding a forward range.

jwezorek
  • 8,592
  • 1
  • 29
  • 46