过滤序列相当于将一个值序列转换为最多一个值的序列序列,然后将它们连接起来。也就是说,过滤出偶数值<0,1,2,3>
与将其转换为序列相同<<0>,<>,<2>,<>>
并连接以产生<0,2>
.
对于 C++17,这需要的代码非常少。我们将从我们自己的值和序列类型开始(您可以轻松地将std::integer_sequence
to a value_sequence
):
template <auto >
struct value { };
template <auto... Vals>
struct value_sequence { };
我们使用自己的原因是我们可以向其中添加运算符。喜欢+
:
template <auto... As, auto... Bs>
constexpr value_sequence<As..., Bs...> operator+(value_sequence<As...>,
value_sequence<Bs...> )
{
return {};
}
我们将使用它进行串联。接下来,我们添加一个函数将单个值转换为包含零个或一个元素的序列:
template <auto Val, class F>
constexpr auto filter_single(value<Val>, F predicate) {
if constexpr (predicate(Val)) {
return value_sequence<Val>{};
}
else {
return value_sequence<>{};
}
}
最后,我们只需要我们的顶级filter
把它们放在一起:
template <auto... Vals, class F>
constexpr auto filter(value_sequence<Vals...>, F predicate) {
return (filter_single(value<Vals>{}, predicate) + ...);
}
原始示例的用法:
constexpr auto evens = filter(
value_sequence<0, 1, 2, 3, 4, 5, 6, 7, 8, 9>{},
[](int i) constexpr { return i%2 == 0; });
C++17 多酷啊!