2013-08-21 14 views
6

Vorrei sapere se è possibile filtrare i tipi passati a un modello variadic (basato su un modello di predicato) per produrre un altro modello variadic contenente quei tipi che soddisfano il predicato:Filtrare i tipi di un pacchetto di parametri

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

Come si può vedere, non ho trovato un modo per "estrarre" il pacchetto di parametri dal resto dei tipi filtrati.

Grazie in anticipo!

risposta

6

Questo dovrebbe essere abbastanza semplice. Al centro si dovrebbe avere qualcosa di simile:

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

Hai solo bisogno Cons<T, Tuple>, che si trasforma in T, std::tuple<Args...>std::tuple<T, Args...>, ed è necessario passare il predicato lungo (lasciato come esercizio). Cons potrebbe apparire così:

template <typename, typename> struct Cons; 

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

Il risultato di filter<Args...>::type sarebbe std::tuple<Brgs...>, dove Brgs... è un pacchetto composto da soli quei tipi in Args... per i quali il predicato detiene.

+0

C'è qualcosa che non riesco ancora a capire, ma gli errori del compilatore non stanno aiutando. Ho postato qui http://ideone.com/USTnJR, se non ti dispiace dare un altro sguardo - non sembra corretto modificare l'originale. – scry

+0

Quella versione ha avuto un altro problema, usa questo: http://ideone.com/eh3Epd. Come puoi vedere, i membri :: type di filter e Contro non sono riconosciuti come tipi. – scry

+0

@roysc: 'Cons' dovrebbe essere specializzato per le tuple. Lasciami modificare questo. [Modifica:] Fatto. Ho anche modificato il modello principale per avere un caso base corretto. –

Problemi correlati