【问题标题】:Why can't a range be sorted in range-v3?为什么不能在 range-v3 中对范围进行排序?
【发布时间】:2020-02-21 11:52:07
【问题描述】:

使用 Range-v3(0.10.0 版)库,我试图从 std::vector 构造一个范围,将其转换为另一个范围,最后对该范围进行排序。我预计排序步骤会产生另一个我以后可以使用的范围。但我能想到的最好的是:

std::vector<std::string> const input { "2", "3", "1" };
using namespace ranges;
std::vector<int> output = input
    | views::transform([](std::string s) { return std::stoi(s); })
    | to<std::vector>()
    | actions::sort

注意在转换步骤之后和排序步骤之前使用to&lt;std::vector&gt;()。这似乎分配了一个新的std::vector,而我只想对转换步骤产生的范围进行排序。

为什么没有 view::sort ?它非常适合上述范围的组成。

【问题讨论】:

  • 考虑如何实现一个假设的view::sort

标签: c++ c++20


【解决方案1】:

转换后的范围只是一个视图,元素在视图迭代时一次生成一个。它无法排序,因为没有地方可以存储已排序的元素。假设的实现也将是低效的,因为每次需要对排序进行比较时都必须转换每个元素。

您的解决方案是将转换后的元素存储在向量中然后对它们进行排序是正确的。

【讨论】:

  • 当您查看 C# 中的 Enumerable.OrderBy(...) 或 Java 中的 Stream.sorted(...) 时:这些函数都接受并产生“范围”,因此它们有助于各自库的可组合性。与用这些语言做同样事情的程序方式相比,我也看不到任何关于效率的重大缺点。所以我认为在 C++ 中也应该有同样的可能。在这种情况下,ranges-v3 的作者是否为了速度而牺牲了风格?
  • 这两个都可能在内部生成一个元素列表,c++ api只是让你明确要求它这样做,这样你在对百万元素视图进行排序时不会感到惊讶使用大量内存
  • 一个向量是一个范围?
  • 它会中断视图管道,因为临时向量不是视图。如果您想要进一步的急切处理,请使用操作。如果你想要懒惰,请将向量存储到一个变量中,这样它就不是临时的了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-11
  • 2019-08-15
  • 1970-01-01
  • 2015-06-03
  • 2014-08-13
  • 1970-01-01
相关资源
最近更新 更多