如何在始终选择第一个元素并过滤其余元素的范围内创建视图?

Pap*_*ter 2 c++ c++20 std-ranges

我有一个价值观的集合:

auto v = std::vector{43, 1, 3, 2, 4, 6, 7, 8, 19, 101};
Run Code Online (Sandbox Code Playgroud)

我想在这个值集合上应用遵循以下条件的视图:

  • 应始终选择第一个元素。
  • 从下一个元素中,仅选择偶数,直到...
  • ...查找等于或大于 6 的元素。

这是我尝试过的视图:

auto v = std::vector{43, 1, 3, 2, 4, 6, 7, 8, 19, 101};
auto r = v |
    std::views::take(1) |
    std::views::filter([](const int x) { return !(x & 1); }) |
    std::views::take_while([](const int x) { return x < 6; });

for (const auto &x : r)
    std::cout << x << ' ';
Run Code Online (Sandbox Code Playgroud)

但执行甚至没有进入打印循环,因为视图是空的。我的猜测是所有标准都会立即应用:

  1. 选择第一个元素 (43)。
  2. 是奇数。
  3. 观看结束。

我所期待的:

  1. 选择第一个元素而不检查任何内容。
  2. 从其余元素中,仅过滤偶数 ( 2, 4, 6, 8)。
  3. 从过滤的元素中,选择数字,直到出现等于或大于 6 的数字 ( 2, 4)。
  4. 43 2 4被打印。

如何对我的值集合建立一个符合我预期的行为的视图?

康桓瑋*_*康桓瑋 6

使用range-v3,您可以用来views::concat连接范围的第一个元素和剩余的过滤元素,例如:

auto v = std::vector{43, 1, 3, 2, 4, 6, 7, 8, 19, 101};
auto r = ranges::views::concat(
  v | ranges::views::take(1),
  v | ranges::views::drop(1)
    | ranges::views::filter([](const int x) { return !(x & 1); })
    | ranges::views::take_while([](const int x) { return x < 6; })
);
Run Code Online (Sandbox Code Playgroud)

演示