Bomaz
Bomaz

Reputation: 1961

Instantiating a parameter pack of template parameters

I'd like to make a template that takes a pack of templates and instantiates them with the same argument pack.

Unfortunately I can't seem to figure out how to expand a parameter pack inside a parameter pack of templates.

How can I make this compile?

#include<type_traits>
#include <tuple>

template <template <typename...> typename... Args>
struct TupleTupleMaker
{
    template <typename... InstantiateWith>
    using NewTupleTuple = typename std::tuple<Args<InstantiateWith...>...>;
};

template<typename a, typename b>
using tuple1 = std::tuple<int,a,b>;

template<typename a, typename b>
using tuple2 = std::tuple<a,b,b>;

using expected = std::tuple<
    std::tuple<int,int,double>,
    std::tuple<int,double,double>>;

using actual = TupleTupleMaker<tuple1,tuple2>::NewTupleTuple<int,double>;

static_assert(std::is_same_v<actual,expected>, "Should be same");

Upvotes: 4

Views: 819

Answers (1)

T.C.
T.C.

Reputation: 137414

Per the direction of core issue 1430, you can't pack expand into an alias template with a fixed parameter list. The workaround is to rewrite tuple1 and tuple2 by routing them through a class template:

template<class a, class b>
struct tuple1_impl { using type = std::tuple<int,a,b>; };

template<typename... a>
using tuple1 = typename tuple1_impl<a...>::type;

template<class a, class b>
struct tuple2_impl { using type = std::tuple<a,b, b>; };

template<typename... a>
using tuple2 = typename tuple2_impl<a...>::type;

Upvotes: 5

Related Questions