假设我有一个基类型和一些派生类型:
struct base {};
struct d1 : base {};
struct d2 : base {};
假设我创建了一个像:
这样的元组std::tuple<double, d1, d2, int> t(1.0, d1(), d2(), 1);
是否可以使用元/运行时编程来生成:
template<typename T>
using my_predicate = std::is_base_of<base, T>;
std::tuple<d1, d2> t_derived = filter(t, my_predicate);
我已经看过堆栈交换的答案,可以让我定义新类型,但我还没想出如何从原始元组中选择运行时组件。堆栈交换帖子在这里:
https://codereview.stackexchange.com/questions/115740/filtering-variadic-template-arguments
答案 0 :(得分:0)
您可以使用以下内容:
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());
}
想法是创建一个过滤后的序列,然后对该序列使用std::tuple_element_t
和std::get
。