range-v3 的 "sliding" 视图是否不适用于惰性范围?

Does range-v3's "sliding" view not work with lazy ranges?

我不明白为什么以下代码无法编译,而注释掉的版本却可以运行。

#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.

正如@康桐薇在评论中所说,问题是 sliding_view 需要 forward_range,但 generate 会产生 input_range

一种解决方法是将生成的范围转储到矢量并创建其滑动视图,或者我相信可以使用自己的生成器编写在 iota 之上,就像这样

#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。我认为这是可行的,因为 iota 生成 forward_range 导致 transform 产生前向范围。