Вы можете обернуть шаблоны формы template<class...> class
в тип тега следующим образом:
#pragma once
// template_tag.hpp
#include <tuple>
#include <type_traits>
template<
template<class...>
class Tmpl_
>
struct TemplateTag {
template<class... Ts>
using insert = Tmpl_<Ts...>;
template<
template<template<class... > class>
class TmplTmpl
>
using rewrap_into = TmplTmpl<Tmpl_>;
};
// convenience helper
template<class TmplTag, class... Ts>
using InsertTemplateArgs = typename TmplTag::template insert<Ts...>;
static_assert(
std::is_same<
InsertTemplateArgs< TemplateTag<std::tuple>, int, bool >,
std::tuple<int, bool>
>{}
);
// convenience helper
template<class TmplTag, template<template<class...> class> class TmplTmpl>
using RewrapTemplateInto = typename TmplTag::template rewrap_into<TmplTmpl>;
template<template<class...> class Tmpl>
struct OtherTemplateTag {};
static_assert(
std::is_same<
RewrapTemplateInto< TemplateTag<std::tuple>, OtherTemplateTag >,
OtherTemplateTag<std::tuple>
>{}
);
Как только ваши шаблоны будут обернуты в тег type , вы можете выполнить итерациютипы как и прежде:
#include <iostream>
#include <string_view>
#include <tuple>
#include <utility>
#include <variant>
#include "loop.hpp"
#include "template_tag.hpp"
template<class T>
std::string_view inspect() {
return __PRETTY_FUNCTION__;
}
using Templates = std::tuple<
TemplateTag<std::tuple>,
TemplateTag<std::tuple>,
TemplateTag<std::pair>,
TemplateTag<std::variant>
>;
template<
template<class...>
class Tmpl
>
struct AnotherTemplateTag {};
int main() {
loop(std::tuple_size<Templates>{}, [&] (auto i) {
using TmplTag = std::tuple_element_t<i, Templates>;
std::cout << i << ": " << inspect<TmplTag>() << "\n";
using AnotherTmplTag = RewrapTemplateInto<TmplTag, AnotherTemplateTag>;
std::cout << " " << inspect<AnotherTmplTag>() << "\n";
using TmplWithArgs = InsertTemplateArgs<TmplTag, int, long>;
std::cout << " " << inspect<TmplWithArgs>() << "\n";
});
}