2016-07-31 23 views
0

, dass ich einen Basistyp haben und einige abgeleitete Typen:Wie kann ich eine Tupelinstanz aus einer anderen Tupelinstanz erstellen, die statisch nur Indizes auswählt, die eine bestimmte Typregel erfüllen? Angenommen

struct base {}; 
struct d1 : base {}; 
struct d2 : base {}; 

Nehmen wir an, ich ein Tupel erstellen wie:

std::tuple<double, d1, d2, int> t(1.0, d1(), d2(), 1); 

Ist es möglich, meta/Runtime-Programmierung verwenden zu generieren:

Ich habe eine Antwort auf Stack-Austausch, die mich den neuen Typ definieren würde, aber ich habe nicht herausgefunden, wie die Laufzeit-Compo ausgewählt aus dem ursprünglichen Tupel. Der Stapelaustausch Beitrag ist hier:

https://codereview.stackexchange.com/questions/115740/filtering-variadic-template-arguments

+3

Also, was ist mit diesem Beitrag hast du verwirrend gefunden? Was hast du versucht, das hat nicht funktioniert? – Barry

+2

Und deine Antwort ist "ja, es ist möglich". – Yakk

+0

Startpunkt: Sie müssen wissen, was der Index der Typen ist, die Ihrem Typprädikat entsprechen. – user2296177

Antwort

0

Sie folgende verwenden:

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

Idee ist eine gefilterte Sequenz zu erzeugen, und dann std::tuple_element_t und std::get mit dieser Sequenz verwenden.