Consider the following class:
// Class definition
template <template <class...> class... Templates>
class template_pack
{
public:
template <class... Types>
constexpr template_pack(const Types&...) noexcept;
};
// Class template argument deduction guide
template <class... Types>
template_pack(const Types&...) -> template_pack</* something here */>
We suppose that the Types...
are of the form template <class...> class... Templates
. What I would like is:
template_pack pack(std::vector<int>{}, std::list<double>{}, std::deque<char>{});
to lead to:
template_pack<std::vector, std::list, std::deque>;
How to make that work?
I "succeed" with additional traits:
template <typename T> struct template_traits;
// Variadic case
template <template <class...> class C, typename ... Ts>
struct template_traits<C<Ts...>>
{
template <typename ... Us>
using template_type = C<Us...>;
};
And then, argument deduction is:
// Class template argument deduction guide
template <class... Types>
template_pack(Types&&...)
-> template_pack<template_traits<std::decay_t<Types>>::template template_type...>;
Issue is that aliases are not really identical (gcc considers some aliases as identical contrary to clang) (I opened a question for that BTW)
template_traits<std::vector>::template_type
is not std::vector
even if for any T
, A
, template_traits<std::vector>::template_type<T, A>
is not std::vector<T, A>
.