如何有条件地链接range :: view?

时间:2019-07-15 20:29:08

标签: c++ c++20 range-v3

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

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

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

已更新

经过一段时间的搜索之后,我只是认为现在唯一可用的选择是您必须将{<1>}逻辑混入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可以提供一些功能,我认为代码看起来比这更直接。

1 个答案:

答案 0 :(得分:1)

我建议不要这样做。代替以下假设代码:

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);
}