代码之家  ›  专栏  ›  技术社区  ›  Roman

级联可变模板参数

  •  1
  • Roman  · 技术社区  · 2 年前

    template <typename... T>
    using Cascade = ???; // T1<T2<T3<...>>>
    

    using Vector2D = Cascade<std::vector, std::vector, double>;
    static_assert(std::is_same_v<Vector2D, std::vector<std::vector<double>>>);
    
    1 回复  |  直到 2 年前
        1
  •  2
  •   n. m. could be an AI    2 年前

    你没有权利。T1不是一个类型名,它是一个模板,其他大多数也是,但最后一个是一个类型名。同一参数包中不能有不同的参数类型(类型和模板)。参数包之后也不能有任何内容。

    你可以这样离开:

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

    std::vector<std::vector<double>> 要比 CascadeLeft<double, std::vector, std::vector>

        2
  •  1
  •   Roman    2 年前

    在公认答案的基础上扩展 CascadeRight

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