I recently learned about the existence of template template parameters and was now wondering if something like this would be possible:
template<template<class... > class Container, typename... args>
struct ContainerTemplate
{
using container = std::tuple<Container<args...>...>;
};
what i want is a template that gets a Container or some other template class as a template template parameter and then expands the rest of the template arguments in such a way that if Container has N template args and i give N * M template arguments for args i get M template instantiations with N template args eg:
ContainerTemplate<std::vector, int, short, char>
//assuming std::vector takes only 1 arg for simplicity
should result in
container = std::tuple<std::vector<int>, std::vector<short>, std::vector<char>>
while
ContainerTemplate<std::map, int, int, short, short>
//assuming std::map takes only 2 args for simplicity
should result in
container = std::tuple<std::map<int, int>, std::map<short, short>>
Is there any way to do this? The question would be wether you could find out how many template args Container takes or not.
Edit: it would be ok if you were required to pass the additional arguments in tuples of size N
ContainerTemplate<std::map, std::tuple<int, int>, std::tuple<short, short>>
Edit2: so i actually found a way to determine the number of template template arguments
template<typename... T>
struct TypeList
{
static const size_t Size = sizeof...(T);
template<typename T2>
struct PushFront
{
typedef TypeList<T2, T...> type_list;
};
};
template<template<class...> class Template, typename... Args>
struct SizeofTemplateTemplate
{
static const size_t Size = 0;
typedef TypeList<> type;
};
template<template<class...> class Template, typename Arg, typename... Args>
struct SizeofTemplateTemplate<Template, Arg, Args...>
{
template<typename... Args>
struct Test;
typedef char yes[1];
typedef char no[2];
template<typename... Args>
struct Test<TypeList<Args...>>
{
template<template<class...> class Template>
static yes& TestTemplate(Template<Args...>* arg);
template<template<class...> class Template>
static no& TestTemplate(...);
};
typedef typename SizeofTemplateTemplate<Template, Args...>::type::PushFront<Arg>::type_list type;
static const size_t Size = sizeof(Test<type>::TestTemplate<Template>(0)) == sizeof(yes) ? type::Size : SizeofTemplateTemplate<Template, Args...>::Size;
};
with this, the following code will print 2
std::cout << SizeofTemplateTemplate<std::vector, int, std::allocator<int>, int, int>::Size << std::endl;
only problem i have now is that dyp's solution crashes the visual studio compiler xD
Edit3: complete solution for the original question here: https://stackoverflow.com/a/22302867/1366591