C++20中的range-v3和zip_with视图适配器

3
使用诸如 ranges::view::reverse 的惰性范围组合器,我可以提供单个参数(例如 reverse(iota(0,3))),也可以使用 operator| 来适应范围(例如 iota(0,3) | reverse)。这种平等性似乎相当规律。下面是零元、一元和二元视图的示例:
#include <range/v3/all.hpp>
#include <iostream>

int main(int argc, char *argv[])
{
  using namespace ranges::view;
  std::cout <<        (iota(0,9) | reverse)      << ' ';
  std::cout << reverse(iota(0,9))                << '\n';

  std::cout <<        (iota(0,9) | chunk(4))     << ' ';
  std::cout <<   chunk(iota(0,9),4)              << '\n';

  std::cout <<        (iota(0,9) | replace(5,0)) << ' ';
  std::cout << replace(iota(0,9),5,0)            << '\n';
  return 0;
}

我注意到ranges::view::zip_with组合器只能用于第二个(非适配器)形式,例如zip_with(std :: plus {},iota(0,9),iota(0,9))。是否有技术原因使zip_with不能被定义为与operator|一起使用?在ranges-v3库中,惰性范围组合器的参数是否有规范顺序?我正在使用ranges-v3库的最新版本(v0.4.0)。"Original Answer"的意思是“最初的回答”。

1
你如何将两个 range 管道传递给一个单一的 zip_view - tkausl
1
你只需要将它们中的一个进行管道传输。 - user2023370
1个回答

6

在range-v3中,r | adapter(x)通常意味着与adapter(r, x)相同。 (实际上,甚至有一种编程语言Elixir,其r |> adapter(x)运算符直接求值为adapter(r, x))。

zip_with的问题在于,如你所指出的那样,使用方式是:

zip_with(std::plus{},iota(0,9),iota(0,9))

这意味着使用 operator| 进行逻辑分离将会是:
std::plus{} | zip_with(iota(0,9),iota(0,9))

但是,左侧不是范围,而是某个二进制运算符。range-v3 是关于链接范围的所有内容。在其他情况下,出现在 | 左侧的是范围。因此,虽然从技术上讲并不难做到,但它似乎是一种实质上不同的事情。


如果您的第一个范围也是可调用的,那么您也会遇到问题,因为现在您在rhs上有zip_with(deduced_potentially_callable, deduced_range) - Caleth
感谢您的输入@Barry。在这种情况下,zip_with可以被定义为将其函数参数放在最后; 即 zip_with(iota(0,9),iota(0,9),std::plus{}) - user2023370
@user2023370 是的,但是 (a) zip_with 接受可变数量的范围,所以函数必须放在第一位;(b) 在其他语言中,函数放在第一位也很常见(例如 Haskell)。 - Barry
那么也许惯例应该是 r | adapter(x) 的意思与 adapter(x,r) 相同? - user2023370

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接