【问题标题】:C++20 ranges and sortingC++20 范围和排序
【发布时间】:2021-01-14 01:28:08
【问题描述】:

我正在处理 C++ 20 的最后 4 个,试图学习新的主要特性。 尝试了一些与范围相关的网络代码,我写了:

std::vector ints{ 6, 5, 2, 8 };
auto even = [](int i) {
    return 0 == i % 2;
};

// ranges...
auto rr = ints | std::views::filter(even) 
               | std::views::transform([](auto i) {
                   return i * i;
                 })
               | std::views::reverse;

然后我会进行排序,就像 range-v3 对 |action::sort 所做的那样,但我知道这个实现是不一样的。

我发现的排序方式是:

ints = std::vector(std::ranges::begin(rr), std::ranges::end(rr));
std::ranges::sort(ints);

我错了吗?有人知道如何使用管道样式对视图进行排序吗?

【问题讨论】:

  • 他们真的为此选择了|??? C++ 每次发布都变得更加晦涩...如果重用经典运算符,它应该是&,因为应该有一个逃生舱口(除了 throw)并且& 具有短路语义...
  • @BitTickler | 被选为与 unix 管道的类比,我相信(对于习惯于那种环境的人来说,这很自然)。按位短路是什么意思?
  • @BitTickler | 语法来自 boost::range,大约 2010 年
  • @BitTickler & 没有短路语义。
  • 好吧 - 我承认&| 一样糟糕。但是,某些操作系统具有带有类似符号的命令行 shell 的论点是一个弱论点,恕我直言,因为 C++ 程序员来自各行各业。或者有或者会有明年或者后年使用某种编程语言或环境|作为评论...但是对于 C/C++ 人来说,&| 已经有了固定的含义。另外,我认为这个特性应该带有编译器支持(循环折叠),因此它可以获得自己的新语法。

标签: c++ sorting c++20 std-ranges


【解决方案1】:

然后我会进行排序,就像 range-v3 对 |action::sort 所做的那样......

不,您实际上不能像这样对rr 进行排序:

rr |= ranges::actions::sort; // error

因为rrview。虽然views 可以提供对底层范围的可变访问,但sort 还需要该范围来支持随机访问。像rr 这样延迟生成的view 不允许这样做。

您可以像之前那样从rr 创建一个vector,然后您可以在该范围内使用actions

ints |= ranges::actions::sort;  // ok

c++20 然而,没有任何 actions(希望我们能在 c++23 中得到它们),所以在此之前你必须在没有管道语法的情况下调用算法 sort

std::ranges::sort(ints);  // ok

【讨论】:

  • views 可以修改。
  • @Barry 哦,怎么会这样?我认为views 就像span 一样,因为它不拥有基础范围,但与span 不同的是,views 也不允许修改范围。
  • 非拥有(views::single 尽管)是的,但它们可以提供可变访问。 span<int>span<int const> 一样多。
  • 对,这里的问题与视图无关。你可以sort 一个view - 只是sort 需要随机访问,而filter 会丢失(而且你不能sort 一系列prvalues)。
  • 反转随机访问迭代器仍然会给您一个随机访问迭代器,这部分很好。 transform 给你一个prvalue,这使得事情不可排序,但如果它给了一个左值,那很好。例如sort(iota(0u, v.size()) | transform([&v](int i) -> int& { return v[i]; })); 是一种有效的,即使是荒谬的做法,sort(v);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-20
  • 2021-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多