2013-08-21 5 views
6

Ich möchte wissen, ob es möglich ist, die an eine Variadic-Vorlage übergebenen Typen (basierend auf einer Prädikatvorlage) zu filtern, um eine andere Variadic-Vorlage zu erzeugen, die das PrädikatDie Typen eines Parameterpakets filtern

enthält
/** 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; 
}; 

Wie Sie sehen können, habe ich keine Möglichkeit gefunden, das Parameterpaket vom Rest der gefilterten Typen zu "extrahieren".

Vielen Dank im Voraus!

Antwort

6

Das sollte ziemlich geradlinig sein. Im Herzen sollten Sie etwas wie dieses:

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; 
}; 

Sie nur Cons<T, Tuple> benötigen, die T, std::tuple<Args...> in std::tuple<T, Args...> dreht, und Sie müssen das Prädikat passieren entlang (links als Übung). Cons könnte wie folgt aussehen:

template <typename, typename> struct Cons; 

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

Das Ergebnis filter<Args...>::typestd::tuple<Brgs...> wäre, wo Brgs... eine Packung nur aus diesen Typen in Args..., für die das Prädikat hält.

+0

Es gibt etwas, das ich immer noch nicht verstehe, aber die Compilerfehler helfen nicht. Ich habe hier http://ideone.com/USTnJR gepostet, wenn es dir nichts ausmacht, einen anderen Blick zu nehmen - es scheint nicht richtig zu sein, das Original zu bearbeiten. – scry

+0

Diese Version hatte ein anderes Problem, verwenden Sie dieses: http://ideone.com/eh3Epd. Wie Sie sehen können, werden die :: type-Member von Filter und Cons nicht als Typen erkannt. – scry

+0

@roysc: 'Cons 'sollte für Tupel spezialisiert sein. Lass mich das bearbeiten. [Bearbeiten:] Fertig. Ich habe auch die Hauptvorlage geändert, um einen richtigen Basisfall zu haben. –

Verwandte Themen