简体   繁体   中英

Cascade variadic template template parameters

How can I cascade variadic types? Ie:

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>>>);

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.

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>;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM