【问题标题】:shuffle action in ranges-v3范围-v3 中的随机播放动作
【发布时间】:2017-03-29 09:55:44
【问题描述】:

由于 range-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 代理对象和 auto 不能很好地混合 - 以 Eigen 库为例) ))。

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

最好, 理查德

【问题讨论】:

  • 我不使用范围库,但我也对它感兴趣 :) 你能输入编译器诊断信息吗? AFAIK 迭代器是延迟创建的。所以可能你不能洗牌 view::iota,因为数据不像向量中那样存在。您是否尝试过从 view::iota 生成一个向量,然后对其进行洗牌?
  • push_back 正是这样做的。我只是想知道这是否是规范的方法。范围库背后的想法通常被称为流/流融合。您在惰性容器上工作,直到某个时刻(希望是最后)出现一个表现步骤(实际执行和编写)。表现通常使用一些折叠或一些副本来完成。 ::push_back 似乎是后者的(主观上)奇怪的选择。因此我的第二个问题。最终我对动作的解释是错误的,这就是为什么 Caleth 的回答真的很有帮助。
  • 操作在容器上操作,而不是视图。您需要使您的iota_view 具体化-例如使用to_vector - 在将其传递给shuffle 之前。 Try auto container = view::iota(1, 10) | to_vector | action::shuffle(gen);.

标签: c++ c++14 range-v3


【解决方案1】:

您的t 实例是一个动作,而不是一个范围。这就是它不是&lt;&lt;able 的主要原因。

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

#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";
}

【讨论】:

  • 我认为你在std::vector&lt;int&gt;之后缺少{}
  • 啊!我确实将 push_back 操作解释为视图操作转换,但是当将其视为修改空容器的操作时,这实际上回答了我的两个问题。问题在于对动作的(解释性)视角问题,而不是类型问题。
猜你喜欢
  • 2011-10-28
  • 1970-01-01
  • 2023-01-23
  • 1970-01-01
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
相关资源
最近更新 更多