Parameter Packet Type Filtering

I would like to know if it is possible to filter the types passed to the variational pattern (based on the predicate pattern) to create another variational pattern containing those types that satisfy the predicate:

/** Filter a parameter pack */ template <template <class> class, template <class...> class, class...> struct filter; template <template <class> class Pred, template <class...> class Variadic> struct filter<Pred, Variadic> : Variadic<> {}; template <template <class> class Pred, template <class...> class Variadic, class T, class... Ts> struct filter<Pred, Variadic, T, Ts...> { // FIXME: this just stops at first T where Pred<T> is true using type = typename std::conditional< Pred<T>::value, Variadic<T, Ts...>, // can't do: Variadic<T, filter<...>> filter<Pred, Variadic, Ts...> >::type; }; 

As you can see, I did not find a way to β€œextract” the parameter package from the rest of the filtered types.

Thanks in advance!

+6
source share
1 answer

This should be pretty straight forward. At heart you should have something like this:

 template <typename...> struct filter; template <> struct filter<> { using type = std::tuple<>; }; template <typename Head, typename ...Tail> struct filter<Head, Tail...> { using type = typename std::conditional<Predicate<Head>::value, typename Cons<Head, typename filter<Tail...>::type>::type, typename filter<Tail...>::type >::type; }; 

You just need Cons<T, Tuple> , which turns T, std::tuple<Args...> into std::tuple<T, Args...> , and you need to pass the predicate (left as an exercise). Cons might look like this:

 template <typename, typename> struct Cons; template <typename T, typename ...Args> struct Cons<T, std::tuple<Args...>> { using type = std::tuple<T, Args...>; }; 

The result of filter<Args...>::type will be std::tuple<Brgs...> , where Brgs... is a package consisting only of those types in Args... for which the predicate is executed.

+7
source

Source: https://habr.com/ru/post/952241/


All Articles