Curious
Curious

Reputation: 21510

How to alias a nested template class with variadic parameter packs

Is there any way one can alias a nested template class with a using keyword? Something like this

template <typename... Types>
struct Something {
    template <typename... TypesTwo>
    struct Another {};
};

template <typename... Types>
template <typename... TypesTwo>
using Something_t = typename Something<Types...>::template Another<TypesTwo...>;

int main() {
    Something_t<int><double>{};
    return 0;
}

This answer template template alias to a nested template? shows a way to do that but that will no longer work if both the parameter packs are variadic, as the compiler will not know where to start and where to end the type lists.

Upvotes: 10

Views: 1159

Answers (2)

Aconcagua
Aconcagua

Reputation: 25518

Not a standalone answer, but an addition to max66's answer:

You could have tried this:

template<typename ... TT, typename ... TTT>
using Alias = typename Something<TT...>::Another<TTT...>;

Looks really nice at first, doesn't it?

Problem then, however will already be with one single template parameter:

Alias<int> a;

Which one is it now? Something<int>::Another<> or Something<>::Another<int>? And if you have more parameters, how to distribute? No chance to get a meaningful solution. So no, you can't do that directly, you have to help yourself with tricks such as max66 proposed...

Upvotes: 0

max66
max66

Reputation: 66200

Not exactly what you asked but... if you can wrap your variadic type lists as arguments of tuples (or similar classes)...

#include <tuple>

template <typename ... Types>
struct Something
 {
   template <typename ... TypesTwo>
   struct Another {};
 };

template <typename, typename>
struct variadicWrapper;

template <typename ... Ts1, typename ... Ts2>
struct variadicWrapper<std::tuple<Ts1...>, std::tuple<Ts2...>>
 { using type = typename Something<Ts1...>::template Another<Ts2...>; };

template <typename T1, typename T2>
using Something_t = typename variadicWrapper<T1, T2>::type;

int main()
 {
   Something_t<std::tuple<int>, std::tuple<double>>{};
 }

Upvotes: 2

Related Questions