【问题标题】:Variadic data structure template instantiation可变数据结构模板实例化
【发布时间】:2020-07-15 10:01:40
【问题描述】:

以下网页有一个可变参数数据结构(元组)link 的示例。我对以下代码有疑问,据称该代码会生成以下类层次结构。我的问题是,层次结构是如何产生的?我没有看到新的struct type<Ts...> 是在哪里生成的?谢谢

template <class... Ts> struct tuple {};

template <class T, class... Ts>
struct tuple<T, Ts...> : tuple<Ts...> {
  tuple(T t, Ts... ts) : tuple<Ts...>(ts...), tail(t) {}

  T tail;
};

类层次结构:

tuple<double, uint64_t, const char*> t1(12.2, 42, "big");
struct tuple<double, uint64_t, const char*> : tuple<uint64_t, const char*> {
  double tail;
}

struct tuple<uint64_t, const char*> : tuple<const char*> {
  uint64_t tail;
}

struct tuple<const char*> : tuple {
  const char* tail;
}

struct tuple {
}

【问题讨论】:

    标签: c++ variadic-templates


    【解决方案1】:

    这里有两个类模板

    template <class... Ts> struct tuple {}; #1
    

    template <class T, class... Ts>
    struct tuple<T, Ts...> : tuple<Ts...> { ... } #2
    

    在这种情况下发生的情况是 #2 被认为更专业,所以当你有

    tuple<double, uint64_t, const char*> 
    

    #2 被淘汰给你

    struct tuple<double, uint64_t, const char*> : tuple<uint64_t, const char*> 
    

    这一直在创建你拥有的链,直到你到达​​p>

    struct tuple<const char*> : tuple {
      const char* tail;
    }
    

    这里: tuple没有参数,所以它唯一可以调用的模板是#1,然后生成

    struct tuple {};
    

    【讨论】:

    • 在您的倒数第二条评论中,您的意思是tuple&lt;&gt;
    【解决方案2】:

    当无法从类型列表中提取单个类型时(即该列表为空),以下代码生效:

    template <class... Ts> struct tuple {};
    

    这是一个空结构,它成为其余类的基础。

    如果至少有一种类型,编译器会将列表分为class T 和其余(列表中少一种类型):

    template <class T, class... Ts>
    struct tuple<T, Ts...> : tuple<Ts...> {
      tuple(T t, Ts... ts) : tuple<Ts...>(ts...), tail(t) {}
    
      T tail;
    };
    

    【讨论】:

    • 我看不出这是如何生成下一个struct tuple&lt;Ts...&gt;
    • 当使用模板特化但尚未明确定义时,编译器会生成它。这就是 all 模板的工作方式。 tuple&lt;T, Ts...&gt; 的每个特化都通过子类化“使用”tuple&lt;Ts...&gt;。因此,如果需要,使用任何 tuple 特化创建该类及其所有超类。
    • 如果编译器发现列表可以被划分(sizeof...(Ts) &gt; 0),它会将列表划分为单一类型(T)和其他类型,并应用第二条规则。 sizeof...(Ts) 迟早会变成 0。编译器会应用第一条规则。
    • 拥有tuple&lt;Ts...&gt;的派生类就足以让编译器生成`struct tuple?
    • 这足以生成派生自派生自派生自...派生自基的类,其中基是空结构。只要成员是公开的,您就不会感觉到差异。
    猜你喜欢
    • 2021-07-01
    • 2013-10-28
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 2014-06-30
    • 1970-01-01
    相关资源
    最近更新 更多