gpt4 book ai didi

c++ - 如何过滤 std::integer_sequence

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:59:16 24 4
gpt4 key购买 nike

如果我理论上有一个整数序列,比如

std::integer_sequence<int, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9>

我如何使用一些编译时谓词过滤它以获得可能更小的 std::integer_sequence<int, ...>

为了论证,假设我只想要偶数值,这导致了“我怎样才能使以下 static_assert(或接近的东西)通过?”的问题

static_assert(std::is_same_v<std::integer_sequence<int, 0, 2, 4, 6, 8>,
decltype(FilterEvens(std::integer_sequence<int, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9>{}))>,
"Integer sequences should be equal");



这个问题的灵感来自于思考我们如何完成删除两个位集 (this question) 之间的重复项,假设我们可以将位集表示为 integer_sequences。仅包含 0 和 1。如果您也能以这种方式解决该问题,则可加分

最佳答案

过滤一个序列相当于将一个值序列转换成一个至多一个值的序列序列,然后将它们串联起来。即从<0,1,2,3>中过滤偶数值与将其转换为序列 <<0>,<>,<2>,<>> 相同并连接产生 <0,2> .

使用 C++17,这需要非常少的代码。我们将从我们自己的值和序列类型开始(您可以轻松地将 std::integer_sequence 转换为 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 多酷啊!

关于c++ - 如何过滤 std::integer_sequence,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41723704/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com