ranges-v3 中的洗牌动作

shuffle action in ranges-v3

由于 ranges-library 已准备好纳入标准,因此我对它进行了一段时间的研究,但我在非常基本的概念上遇到了一些问题。

我苦苦挣扎的玩具示例是这样的:

#include <iostream>
#include <range/v3/all.hpp>
using namespace ranges;


int main (int argc, char const* argv[]) {
    auto v = view::iota(1, 10);
    std::default_random_engine gen;
    auto t = action::push_back(view::iota(0, 10)) | action::shuffle(gen);
    std::cout << t << "\n";
}

它不可打印的事实向我表明 t 并不是一个合适的范围。不幸的是,文档(如果有的话)确实滥用了 auto,所以我不知道发生了什么。我必须做什么,为什么我必须这样做(万一有人知道:如何记录结果类型(imo 代理对象和自动不能很好地混合 - 以 Eigen 库为例)).

我的第二个问题与货物崇拜有关action::push_back。如果我省略它,我会收到一个概念错误,告诉我 iota 生成的视图需要是可变的。显然视图在设计上是不可变的,所以我在这里遇到了问题,但是 "pushing nothing" 真的是将事物提升到 mutable/stateful 对象中的首选方法还是有其他选择?

最好的, 理查德

您的 t 实例是一个动作,而不是一个范围。这就是它无法 << 的主要原因。

您可以通过将其应用于多个容器来查看,例如

#include <iostream>
#include <experimental/iterator>
#include <range/v3/all.hpp>
using namespace ranges;


int main (int argc, char const* argv[]) {
    std::default_random_engine gen;
    auto t = action::push_back(view::iota(0, 10)) | action::shuffle(gen);
    auto v1 = std::vector<int>{} | t;
    auto v2 = std::vector<int>{} | t;
    auto v3 = std::vector<int>{} | t;
    auto v4 = std::vector<int>{} | t;
    std::copy(v1.begin(), v1.end(), std::experimental::make_ostream_joiner(std::cout, ", "));
    std::cout << "\n";
    std::copy(v2.begin(), v2.end(), std::experimental::make_ostream_joiner(std::cout, ", "));
    std::cout << "\n";
    std::copy(v3.begin(), v3.end(), std::experimental::make_ostream_joiner(std::cout, ", "));
    std::cout << "\n";
    std::copy(v4.begin(), v4.end(), std::experimental::make_ostream_joiner(std::cout, ", "));
    std::cout << "\n";
}