如何链接范围::有条件地查看

How to chain ranges::view conditionally?

本文关键字:有条件 范围 何链接 链接      更新时间:2023-10-16

简单地说,如何在view链结构上以编程方式分支?

因为现在我能想到的只是#if,这不是一个好主意。

auto adaptor =
   view::drop(x0)
#if branch1
   | view::drop(x1)
#elif branch2
   | view::filter(ft1)
#endif
   | view::stride(s1);

更新

在谷歌搜索了一段时间之后,我只是认为现在唯一可用的选择是你必须将逻辑">混合"到view::xxx_while或任何具有可变 lambda 或其他任何东西的可预测视图中。

然而,事实证明已经很糟糕了。

auto adaptor =
   view::drop(x0)
   | view::drop_while([captures](auto&&) mutable { ...blend it here... })
   | view::filter([captures](auto&&) mutable { ..blend it here... })
   | view::stride(s1);

无论如何,如果将来view::enable_if可以使用一些方法,我认为代码看起来会比这更直接。

我建议不要这样做。而不是这个假设的代码:

auto adaptor =
   view::drop(x0)
#if branch1
   | ranges::drop(x1)
#elif branch2
   | ranges::filter(ft1)
#endif
   | ranges::stride(s1);

应将该逻辑合并到筛选器中:

auto adaptor =
   view::drop(x0)
   | ranges::filter([](auto&& x){ return branch2 && ft1(x); })
   | ranges::stride(s1);

如果你真的想用一些编译时值来组合一个范围适配器,你可以使用 if 语句,如下所示:

auto get_adapter() {
    if constexpr(branch1)
        return view::drop(x0) | ranges::drop(x1) | ranges::stride(s1);
    else if constexpr (branch2)
        return view::drop(x0) | ranges::filter(ft1) | ranges::stride(s1);
    else
        return view::drop(x0) | ranges::stride(s1);
}