Создание кортежа типов, полученных из Variadi c Template Pack - PullRequest
2 голосов
/ 26 января 2020

Учитывая список значений size_t в виде пакета параметров шаблона c, как можно создать кортеж из производных типов (например, Matrix) в зависимости от пакета параметров таким образом, чтобы n-й элемент переменной c генерирует Matrix<n, n+1>. Например:

make_matrix_tuple<2,3,4,5>() == make_tuple( Matrix<2,3>, Matrix<3,4>, Matrix<4,5> );

Как написать функцию make_matrix_tuple с набором параметров size_t?

Под производным типом я подразумеваю не наследование, а зависимость (?). Я не уверен, что является правильным термином.
Распаковка пакета параметров достаточно проста

template <typename ElementType, size_t... Sizes>
void make_tuple_of_vectors() { std::tuple < std::array<ElementType, Sizes> ... > tuple; }

Однако я считаю, что немного над головой, когда речь идет о следующей части. Я пытался рекурсивно распаковать пару аргументов из пакета параметров следующим образом:

template <typename Type, size_t size1, size_t size2>
struct dummy_matrix
{
    size_t SIZE1 = size1;
    size_t SIZE2 = size2;
    using type = Type;
};

template <size_t Iterator, typename ElementType, size_t T, size_t... Sizes>
struct unpack_two
{
    using type = typename unpack_two<Iterator - 1, ElementType, Sizes...>::type;
};

template<typename ElementType, size_t T, size_t T2, size_t... Sizes>
struct unpack_two<0, ElementType, T, T2, Sizes...>
{ 
    using type = dummy_matrix<ElementType, T, T2>;
};

Так что unpack_two<N, Type, Sizes...>::type дает N-й и (N + 1) -й тип матрицы.
С этим, Я застрял с чем-то, что мне кажется разумным, но компилятор резко не согласен.

template <size_t... Sizes, size_t... Is>
auto
foo_impl(std::index_sequence<Is...>) {
    std::tuple < unpack_two<Is, float, Sizes ... >::type ... > tuple; 
    return tuple; 
}
template <size_t... Args>
void foo()
{
    auto vs = foo_impl<Args...>(std::make_index_sequence<sizeof...(Args)-1>{});
}
int main() { foo<6,9,12>(); }

Я пытаюсь распаковать список std::size_t размеров для шаблона unpack_two, а затем распаковать std::index_sequence для std::make_tuple().
Буду признателен за объяснения, почему мои попытки не работают, или даже это правильный инструмент std::index_sequence здесь. Но меня больше всего интересует любое решение поставленной проблемы.

1 Ответ

5 голосов
/ 26 января 2020

как сделать кортеж из производных типов (например, Matrix) в зависимости от пакета параметров таким образом, чтобы n-й элемент variadi c генерировал Matrix<n, n+1> [?]

Может быть, использовать constexpr std::array в качестве вспомогательной функции?

Пример

#include <array>
#include <tuple>
#include <utility>

template <std::size_t, std::size_t>
struct Matrix
 { };

template <std::size_t ... Ds, std::size_t ... Is>
auto mmt_helper (std::index_sequence<Is...>)
 {
   constexpr std::array ca { Ds... };

   return std::make_tuple(Matrix<ca[Is], ca[Is+1u]>{}...);
 }

template <std::size_t ... Ds>
auto make_matrix_tuple ()
 { return mmt_helper<Ds...>(std::make_index_sequence<sizeof...(Ds)-1>{}); }

int main ()
 {
   auto mt = make_matrix_tuple<2,3,4,5>();

   using T1 = decltype(mt);
   using T2 = std::tuple<Matrix<2u, 3u>, Matrix<3u, 4u>, Matrix<4u, 5u>>;

   static_assert( std::is_same_v<T1, T2> );
 }
...