在 c++17 中过滤类型的元组

the*_*ang 7 c++ templates tuples c++17

std::tuple a{1,3,4,5} -> 使其成为大于 3 的数字

std::tuple b{4,5}    
Run Code Online (Sandbox Code Playgroud)

或者

std::tuple a{
    std::integral_constant<int,1> {},
    std::integral_constant<int,3> {},
    std::integral_constant<int,4> {},
    std::integral_constant<int,5> {} 
}
Run Code Online (Sandbox Code Playgroud)

std::tuple a{
    std::integral_constant<int,4>{},
    std::integral_constant<int,5>{}
};
Run Code Online (Sandbox Code Playgroud)

如何在编译时转换它?我可以使用integer_sequence它来做到这一点,但这很麻烦。在 C++17 中是否有更简单的方法使用折叠表达式或std::apply

同样在过滤器之后,还需要获取唯一条目的元组。但我的假设是,如果可以进行过滤,那么找到唯一值将是微不足道的。

编辑以便更清楚: std::tuple<int_c<1>, int_c<3>,int_c<4>,int_c<5>> to std::tuple<int_c<4>,int_c<5><-- 如果可以在没有额外声明函数的情况下以简洁的 c++17 方式实现,那就可以了!

编辑:我在摆弄,也许这样的事情会奏效:

template... C作为积分常数列表:

constexpr auto result = std::tuple_cat(std::conditional_t<(C::value > 3), std::tuple<C>, std::tuple<>>{}...);
Run Code Online (Sandbox Code Playgroud)

Jar*_*d42 10

tuple_cat用 c++17来实现你的:

constexpr auto result = std::apply([](auto...ts) {
    return std::tuple_cat(std::conditional_t<(decltype(ts)::value > 3),
                          std::tuple<decltype(ts)>,
                          std::tuple<>>{}...);
}, tup);
Run Code Online (Sandbox Code Playgroud)


Gui*_*cot 1

您可以使用 C++17 中的新 STL 实用程序来做到这一点。那会是这样的:

template<typename T>
auto filter(T tup) {
    return std::apply([&](auto first, auto... rest) {
        auto filtered_rest = [&]{
            if constexpr (sizeof...(rest)) {
                return filter(std::tuple{rest...});
            } else {
                return std::tuple{};
            }
        }();

        if constexpr (first > 3) {
            return std::tuple_cat(std::tuple{first}, filtered_rest);
        } else {
            return filtered_rest;
        }
    }, tup);
}
Run Code Online (Sandbox Code Playgroud)

当然,还有很多其他方法可以做到这一点。在本例中我使用了std::apply和 递归。我从一个空元组开始,一次添加一个元素。

实例: https: //godbolt.org/z/qo63r4