Типы фильтров в пакете параметров - PullRequest
0 голосов
/ 31 января 2020

Я пытаюсь создать отфильтрованный тип шаблона * / variadi c, а также сохранить порядок.

// example what im trying to accomplish
template<typename... Args>
struct query
{
    using filtered = typename filtered<std::is_integral_v, Args...>
}

В этом примере с фильтром будут отфильтрованы все целые типы, например.

query<int, A, B>::filtered == query<A, B>::filtered

Как я могу создать утилиту, подобную этой, или что-то подобное, чтобы достичь тех же результатов

Ответы [ 3 ]

2 голосов
/ 31 января 2020

С Boost.Mp11 , это короткий однострочный (как всегда):

using filtered = mp_filter<std::is_integral, mp_list<Args...>>;

Обратите внимание, что если вы хотите, чтобы это было std::tuple, это:

using filtered = mp_filter<std::is_integral, std::tuple<Args...>>;
1 голос
/ 31 января 2020

Вы можете избежать рекурсии, используя std::tuple_cat()

#include <type_traits>
#include <tuple>

template <template <typename> class F, typename T>
std::enable_if_t<true == F<T>::value, std::tuple<>> filter ();

template <template <typename> class F, typename T>
std::enable_if_t<false == F<T>::value, std::tuple<T>> filter ();

template <typename...>
struct query;

template <typename ... Ts>
query<Ts...> deTuple (std::tuple<Ts...>);

template <template <typename> class F, typename ... Ts>
struct filtered
 { using type = decltype(std::tuple_cat(filter<F, Ts>()...)); };

template<typename... Args>
struct query
{
    using filtered = decltype(deTuple(std::declval<
      typename filtered<std::is_integral, Args...>::type>()));
};

class A {};
class B {};

int main ()
 {
   using T1 = typename query<int, A, B>::filtered;
   using T2 = query<A, B>;

   static_assert( std::is_same_v<T1, T2> );
 }
1 голос
/ 31 января 2020

Комментарий @ Jarod42 имеет демо с рабочим кодом

#include <tuple>
#include <type_traits>

template<template<class> class, template<class...> class, class...>
struct filter;
template<template<class> class Pred, template<class...> class Variadic>
struct filter<Pred, Variadic>
{
    using type = Variadic<>;
};

template<template<class> class Pred,
         template<class...> class Variadic,
         class T,
         class... Ts>
struct filter<Pred, Variadic, T, Ts...>
{
    template<class, class>
    struct Cons;
    template<class Head, class... Tail>
    struct Cons<Head, Variadic<Tail...>>
    {
        using type = Variadic<Head, Tail...>;
    };

    using type = typename std::conditional<
      Pred<T>::value,
      typename Cons<T, typename filter<Pred, Variadic, Ts...>::type>::type,
      typename filter<Pred, Variadic, Ts...>::type>::type;
};

и интеграцию с моим примером


template<typename... Args>
struct query
{
    using filtered = filter<std::is_integral, std::tuple, Args...>::type
}

...