【问题标题】:Creating tuple of types derived from Variadic Template Pack创建从 Variadic Template Pack 派生的类型的元组
【发布时间】:2020-01-26 19:46:11
【问题描述】:

给定一个 size_t 值列表作为可变参数模板参数包,如何根据参数包生成派生类型的元组(例如矩阵),使可变参数的第 n 个元素生成 Matrix<n, n+1> .例如:

make_matrix_tuple<2,3,4,5>() == make_tuple( Matrix<2,3>, Matrix<3,4>, Matrix<4,5> );

如何编写make_matrix_tuple函数,传入size_t的参数包?

我所说的派生类型不是指继承,而是依赖(?)。我不确定正确的术语是什么。
解压参数包很简单

template <typename ElementType, size_t... Sizes>
void make_tuple_of_vectors() { std::tuple < std::array<ElementType, Sizes> ... > tuple; }

但是,我相信我在谈到下一部分时有点过头了。 我正在尝试从参数包中递归解压缩一对参数,如下所示:

template <typename Type, size_t size1, size_t size2>
struct dummy_matrix
{
    size_t SIZE1 = size1;
    size_t SIZE2 = size2;
    using type = Type;
};

template <size_t Iterator, typename ElementType, size_t T, size_t... Sizes>
struct unpack_two
{
    using type = typename unpack_two<Iterator - 1, ElementType, Sizes...>::type;
};

template<typename ElementType, size_t T, size_t T2, size_t... Sizes>
struct unpack_two<0, ElementType, T, T2, Sizes...>
{ 
    using type = dummy_matrix<ElementType, T, T2>;
};

所以unpack_two&lt;N, Type, Sizes...&gt;::type 给出第 N 和第 (N+1)-n 矩阵类型。
有了这个,我坚持了一些对我来说似乎明智的事情,但编译器却强烈反对。

template <size_t... Sizes, size_t... Is>
auto
foo_impl(std::index_sequence<Is...>) {
    std::tuple < unpack_two<Is, float, Sizes ... >::type ... > tuple; 
    return tuple; 
}
template <size_t... Args>
void foo()
{
    auto vs = foo_impl<Args...>(std::make_index_sequence<sizeof...(Args)-1>{});
}
int main() { foo<6,9,12>(); }

我正在尝试解压缩 unpack_two 模板的 std::size_t 大小列表,然后解压缩 std::index_sequencestd::make_tuple()
我会很感激解释为什么我的尝试失败了,甚至是std::index_sequence 正确的工具。但我最感兴趣的是提出问题的任何解决方案。

【问题讨论】:

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


    【解决方案1】:

    如何根据参数包生成派生类型(例如矩阵)的元组,使可变参数的第 n 个元素生成 Matrix&lt;n, n+1&gt; [?]

    也许在辅助函数中使用constexpr std::array

    一个例子

    #include <array>
    #include <tuple>
    #include <utility>
    
    template <std::size_t, std::size_t>
    struct Matrix
     { };
    
    template <std::size_t ... Ds, std::size_t ... Is>
    auto mmt_helper (std::index_sequence<Is...>)
     {
       constexpr std::array ca { Ds... };
    
       return std::make_tuple(Matrix<ca[Is], ca[Is+1u]>{}...);
     }
    
    template <std::size_t ... Ds>
    auto make_matrix_tuple ()
     { return mmt_helper<Ds...>(std::make_index_sequence<sizeof...(Ds)-1>{}); }
    
    int main ()
     {
       auto mt = make_matrix_tuple<2,3,4,5>();
    
       using T1 = decltype(mt);
       using T2 = std::tuple<Matrix<2u, 3u>, Matrix<3u, 4u>, Matrix<4u, 5u>>;
    
       static_assert( std::is_same_v<T1, T2> );
     }
    

    【讨论】:

    • 接受了,比我尝试做的要干净得多。是否可以调整它以便我可以获得创建的元组的类型?看来非静态数据成员不能具有包含 auto 的类型。
    • @MkjG Jup, here 就是一个例子。
    • @MkjG - 你应该展示一个使用示例......无论如何......decltype()是你的朋友;您可以按照 Timo 的链接作为示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 2014-09-29
    • 2023-01-26
    相关资源
    最近更新 更多