Filter the types of a parameter pack

c++, c++11, metaprogramming, variadic-templates

Solution

That should be fairly straight-forward. At the 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 along (left as an exercise). `Cons` could 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` would be `std::tuple<Brgs...>`, where `Brgs...` is a pack consisting of only those types in `Args...` for which the predicate holds.

Problem

I'd like to know if it's possible to filter the types passed to a variadic template (based on a predicate template) to produce another variadic template containing those types which 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 haven't found a way to "extract" the parameter pack from the rest of the filtered types. Thanks in advance!

Original source