How can I cascade variadic types? I.e.:
template <typename... T>
using Cascade = ???; // T1<T2<T3<...>>>
Example:
using Vector2D = Cascade<std::vector, std::vector, double>;
static_assert(std::is_same_v<Vector2D, std::vector<std::vector<double>>>);
CodePudding user response:
You cannot have CascadeRight. T1 is not a typename, it is a template, and so are most of the others, but the last one is a typename. You cannot have different parameter kinds (both types and templates) in the same parameter pack. You also cannot have anything after a parameter pack.
You can have CascadeLeft like this:
template <typename K, template <typename...> class ... T>
class CascadeLeft;
template <typename K>
class CascadeLeft<K>
{
using type = K;
};
template <typename K,
template <typename...> class T0,
template <typename...> class... T>
class CascadeLeft<K, T0, T...>
{
using type = typename CascadeLeft<T0<K>, T...>::type;
};
Frankly, std::vector<std::vector<double>>
is much more transparent than CascadeLeft<double, std::vector, std::vector>
, so I wouldn't bother.
CodePudding user response:
Expanding on the accepted answer with CascadeRight
and support for multiple types for the innermost template:
template<template<typename...> typename Head, template<typename...> typename... Tail>
struct CascadeRight {
template<typename... T>
using type = Head<typename CascadeRight<Tail...>::type<T...>>;
};
template<template<typename...> typename Head>
struct CascadeRight<Head> {
template<typename... T>
using type = Head<T...>;
};
template<template<typename...> typename Head, template<typename...> typename... Tail>
struct CascadeLeft {
template<typename... T>
using type = typename CascadeLeft<Tail...>::type<Head<T...>>;
};
template<template<typename...> typename Head>
struct CascadeLeft<Head> {
template<typename... T>
using type = Head<T...>;
};
using T1 = CascadeRight<std::vector, std::map>::type<int, double>;
using T2 = CascadeLeft<std::map, std::vector>::type<int, double>;