[英]How can I create a tuple instance from another tuple instance that statically selects only indices that satisfy a certain type rule?
Suppose that I have a base type and some derived types: 假设我有一个基本类型和一些派生类型:
struct base {};
struct d1 : base {};
struct d2 : base {};
Suppose that I create a tuple like: 假设我创建了一个元组,例如:
std::tuple<double, d1, d2, int> t(1.0, d1(), d2(), 1);
Is it possible to use meta/runtime programming to generate: 是否可以使用元/运行时编程来生成:
template<typename T>
using my_predicate = std::is_base_of<base, T>;
std::tuple<d1, d2> t_derived = filter(t, my_predicate);
I have looked at an answer on stack exchange that would let me define the new type, but I haven't figured out how to select the runtime components from the original tuple. 我已经看过有关堆栈交换的答案,该答案可以让我定义新类型,但是我还没有弄清楚如何从原始元组中选择运行时组件。 The stack exchange post is here: 堆栈交换帖子在这里:
https://codereview.stackexchange.com/questions/115740/filtering-variadic-template-arguments https://codereview.stackexchange.com/questions/115740/filtering-variadic-template-arguments
You may use the following: 您可以使用以下内容:
template <typename TupleOfIntegralConstant>
struct as_sequence;
template <typename ... Ts>
struct as_sequence<std::tuple<Ts...>> {
using type = std::index_sequence<Ts::value...>;
};
template <template <typename> class Pred, typename Tuple, typename Seq>
struct make_filtered_sequence;
template <template <typename> class Pred, typename Tuple, std::size_t ... Is>
struct make_filtered_sequence<Pred, Tuple, std::index_sequence<Is...>>
{
using type = typename as_sequence<decltype(std::tuple_cat(
std::conditional_t<
Pred<std::tuple_element_t<Is, Tuple>>::value,
std::tuple<std::integral_constant<std::size_t, Is>>,
std::tuple<>>{}...))>::type;
};
template <typename Tuple, std::size_t ... Is>
auto filter_impl(const Tuple& t, std::index_sequence<Is...>)
-> std::tuple<std::tuple_element_t<Is, Tuple>...>
{
return {std::get<Is>(t)...};
}
template <template <typename> class Pred, typename Tuple>
auto filter(const Tuple& t)
{
using filtered_seq = typename make_filtered_sequence<Pred, Tuple, std::make_index_sequence<std::tuple_size<Tuple>::value>>::type;
return filter_impl(t, filtered_seq());
}
Idea is to create a filtered sequence, and then use std::tuple_element_t
and std::get
with that sequence. 想法是创建一个过滤后的序列,然后对该序列使用std::tuple_element_t
和std::get
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.