Уменьшение параметра шаблона внутри выражения сгиба - PullRequest
4 голосов
/ 09 января 2020

Рассмотрим следующий код:

template<typename...>
struct C
{ /* ... */ };

template<typename T, unsigned N>
struct B
{
    using type = /* ... */;
};

template<size_t N, typename... Ts>
struct A
{
    using type = C<typename B<Ts, N-->::type...>; // decrement N sizeof...(Ts) times
};

Так, например,

typename A<5, int, long, void>::type

расширяется до

C<typename B<int, 5>::type, typename B<long, 4>::type, typename B<void, 3>::type>

Так как N является значением const этот код не компилируется. Есть ли другой способ?

Ответы [ 2 ]

9 голосов
/ 09 января 2020

Вычтите std::index_sequence из N

namespace detail {
    template<size_t N, typename... Ts, size_t... Is>
    C<typename B<Ts, N - Is>::type...> A_impl(std::index_sequence<Is...>);
}

template<size_t N, typename... Ts>
struct A
{
    using type = decltype(detail::A_impl<N, Ts...>(std::index_sequence_for<Ts...>{}));
};
1 голос
/ 09 января 2020

Вы можете сделать это с помощью нереализованной или вызванной шаблонной вспомогательной функции static constexpr:

template<size_t N, typename... Ts>
struct A
{
    template<size_t... Is>
    static constexpr auto type_getter(std::index_sequence<Is...>) -> C<typename B<Ts, N-Is>::type...>;
    using type = decltype(type_getter(std::index_sequence_for<Ts...>{}));
};

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...