【问题标题】:Create tuple of vectors from a Typelist从 Typelist 创建向量元组
【发布时间】:2016-09-30 04:31:21
【问题描述】:

我有一个简单的类型列表实现;

template<typename... Ts> 
struct Typelist
{
  static constexpr size_t count{sizeof...(Ts)};
};

我想用它做的是为类型列表中的每种类型生成std::tuplestd::vector&gt;;例如:

struct A {};
struct B {};
struct C {};

using myStructs = typelist<A,B,C>;
using myList = tupleOfVectorTypes<myStructs>; tuple<vector<A>, vector<B>, vector<C>>

这是我一直在玩的:

template<template<typename... Ts> class T>
struct List
{
  using type = std::tuple<std::vector<Ts>...>;
};

但是,它一直在吐槽它需要一个类型。我尝试将 Ts 包装在 decltype 中,如下所示:

using type = std::tuple&lt;std::vector&lt;decltype(Ts)&gt;...&gt;;

但这也是错误的,我猜我也错误地使用了decltype。 那么,如何根据我抛出的类型列表创建类型向量的元组?

【问题讨论】:

    标签: c++ templates vector tuples typelist


    【解决方案1】:

    诀窍是使用专门化来深入了解模板参数。

    -std=c++1z 模式下使用 gcc 5.3.1 测试:

    #include <vector>
    #include <tuple>
    
    template<typename... Ts>
    struct Typelist{
    };
    
    // Declare List
    template<class> class List;
    
    // Specialize it, in order to drill down into the template parameters.
    template<template<typename...Args> class t, typename ...Ts>
    struct List<t<Ts...>> {
        using type = std::tuple<std::vector<Ts>...>;
    };
    
    // Sample Typelist
    
    struct A{};
    struct B{};
    struct C{};
    
    using myStructs = Typelist<A,B,C>;
    
    // And, the tuple of vectors:
    
    List<myStructs>::type my_tuple;
    
    // Proof
    
    int main()
    {
        std::vector<A> &a_ref=std::get<0>(my_tuple);
        std::vector<B> &b_ref=std::get<1>(my_tuple);
        std::vector<C> &c_ref=std::get<2>(my_tuple);
        return 0;
    }
    

    【讨论】:

    • 太棒了!我还在学习一些关于可变参数模板的知识,你能解释一下为什么这完全有效吗?当我查看 template&lt;template&lt;typename...Args&gt; class t, typename ...Ts&gt; struct List&lt;t&lt;Ts...&gt;&gt; { using type = std::tuple&lt;std::vector&lt;Ts&gt;...&gt;; }; 时,我可以看到 List 的类型为 t,它包含 Ts 的类型,但为什么 ...Ts 具有所有类型而不是 ...Args?
    • template&lt;template&lt;typename ...Args&gt; class T&gt; { /* ... */ }; -- 模板看到并且可以访问的唯一类型是T。那是模板参数。 “...Args”不是模板参数。它是模板参数的参数,模板的主体只知道T。 “Args”几乎被忽略了。为了解决这个范围界定问题,特化模板,“List&lt;t&lt;Ts...&gt;&gt;”使Ts... 在某种意义上成为“一等公民”。
    • 啊,我现在明白了。 List 是 T 的一种类型,它的类型是 Ts...,当我将它传递到模板时,它是从它的内部“拉起来”的。我需要停止阅读模板然后函数,并开始阅读函数/类然后模板。
    • 如果您询问专门用于模板的语法,那是它自己的主题。如果您不熟悉什么是专业化,我能给您的最好帮助是向您推荐一本关于 C++ 的好书,该书详细解释了专业化。您无法在 400 个字符的 stackoverflow.com 评论中真正解释专业化。
    【解决方案2】:

    这是实现您想要的另一种方法。它依赖于函数的力量:

    #include <cstddef>
    #include <tuple>
    #include <vector>
    #include <utility>
    
    template<typename... Ts> 
    struct Typelist
    {
      static constexpr size_t count{sizeof...(Ts)};
    };
    
    template<class... ARGS>
    std::tuple<std::vector<ARGS>... > typelist_helper(Typelist<ARGS...>);
    
    template<class T> 
    using vectorOfTuples = decltype(typelist_helper(std::declval<T>()));
    
    struct A{};
    struct B{};
    struct C{};
    
    using testlist = Typelist<A, B, C>;
    vectorOfTuples<testlist> vec;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      • 1970-01-01
      • 2017-09-09
      • 2021-04-23
      • 1970-01-01
      • 2017-04-24
      • 1970-01-01
      相关资源
      最近更新 更多