【问题标题】:Get dependent type of variadic template parameter pack获取依赖类型的可变参数模板参数包
【发布时间】:2020-01-23 19:30:11
【问题描述】:

假设我有:

struct M1 { static constexpr int T = 3; }
struct M2 { static constexpr int T = 8; }
struct M3 { static constexpr int T = 19; }

这确实是两个相互关联的问题:

  1. 存储所有 M 类型的列表以便以后我不必重复自己的最佳方式是什么?

在 Fantasy-c++ 中:using AllMs = <M1, M2, M3>;

  1. 鉴于该列表,我如何获得 M::T 列表(但作为类型)?

在 Fantasy-c++ 中:using AllMTs = AllMs::T ...;(可能使用 std::integral_type)


例如,我可以像这样从所有 O 乘以继承:

template <class... M> class K: public O<M>... { }

template <typename ...P> struct ParameterPackApplicator {
    template <template <typename...> typename T> using apply = T<P...>;
};

using AllM = ParameterPackApplicator<M1, M2, M3>;

using MultiplyInheritedThing = AllM::apply<K>;

...但我似乎无法弄清楚如何获得所有 M::T 的类型列表...

【问题讨论】:

  • “我不必重复自己”是什么意思?你想避免什么重复?
  • 还有2.不太清楚M::T是什么?
  • T 实际上是什么?变量、类型或函数?
  • 我以后想多继承一些东西:class S: public O。并获取这些依赖类型。还有其他的……
  • 为什么要继承?这些类型只有一个静态成员,它们都具有相同的名称

标签: c++ templates template-meta-programming


【解决方案1】:

您不能在 C++ 中创建包的别名。模板包扩展必​​须在引入包的同一上下文中进行。

但是,您可以将它放在一个元组中,然后再将其解包:

using AllMs = std::tuple<M1, M2, M3>;

然后使用索引序列来解包:

template<typename = std::make_index_sequence<std::tuple_size_v<AllMTs>>>
struct MyType;

template<std::size_t... S>
struct MyType<std::index_sequence<S...>> : std::tuple_element_t<S, AllMTs>... {};

当然,对于您的用例来说,这并不是一个好的权衡。您最好从直接拥有包的单个类继承并处理它:

template<typename... AllMs>
struct Inheritance : AllMs... {
    // can do `AllMs::T...` to get all ints
};


struct MyType : Inheritance<M1, M2, M3> {

};

【讨论】:

    【解决方案2】:

    不确定这是否是您想要的,但您可以将可变参数模板与元组结合使用:

    #include <tuple>
    
    struct M1 { int x = 0; };
    struct M2 { int y = 0; };
    
    using allM = std::tuple<M1,M2>;
    
    template <typename ... X>
    struct foo : public X... {};
    
    template <typename ...X>
    struct foo<std::tuple<X...>> : public X... {};
    
    int main() {
        foo<allM> x;
        x.x = x.y;
    }
    

    【讨论】:

      【解决方案3】:

      所以你实际上不能像 Guillaume 建议的那样做 AllMs::T...。或者至少我无法获得正确的语法......不过下面对我有用。

      template <typename... P> struct parameter_pack {
          template <template <typename...> typename T> using apply = T<P...>;
      };
      
      template <typename... P>
      struct TGetter {
          using Ts = std::integer_sequence<int, P::T...>;
      };
      
      using AllTypes = parameter_pack<M1, M2, M3>;
      
      using AllTs = AllTypes::apply<TGetter>::Ts;
      

      【讨论】:

        猜你喜欢
        • 2014-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-01
        • 2011-08-27
        • 1970-01-01
        • 1970-01-01
        • 2010-12-17
        相关资源
        最近更新 更多