如何编写以下问题 C++ 的 TMP 代码

How can I write TMP code of below question C++

我是 TMP 世界的新手,虽然我可以轻松理解代码,但在编写新代码时遇到问题。我得到了以下我无法解决的问题。谁能帮我理解我是怎么做到的。

下面是问题的描述

template<int... Xs> struct Vector; 

可以这样使用:

Vector<1,2,3>

我们想写一个接受多个向量的函数,然后压缩 *.i.e.给定输入

Vector<1,2,3>, Vector<2,3,4>, Vector<3,4,5>

产出:

Vector<6,24,60>

静态实现这种计算的一种常见方法是使用元函数

template <typename... Vectors>
struct zip 
{
    using type = XXXX;
}

其中 XXXX 是 zip 的逻辑。我们可以这样验证:

static_assert(
    std::is_same<
        zip<Vector<1, 2, 3>, Vector<2, 3, 4>, Vector<3, 4, 5>>::type, 
        Vector<6, 24, 60>>::value);

我想知道,如何完成这个逻辑,谢谢。

您选择了一个相当重要的问题作为您对模板元编程的首次尝试。不管怎样,这是我的看法:

template<int... Xs> struct Vector;

template <int... Xs>
constexpr std::size_t vectorSize(Vector<Xs...>*) {
    return sizeof...(Xs);
}

template <typename V>
constexpr std::size_t vectorSize() {
    return vectorSize(static_cast<V*>(nullptr));
}

template <std::size_t I, int... Xs>
constexpr int getVal(Vector<Xs...>*) {
    return std::get<I>(std::make_tuple(Xs...));
}

template <std::size_t I, typename V>
constexpr int getVal() {
    return getVal<I>(static_cast<V*>(nullptr));
}

template <std::size_t I, typename... Vs>
constexpr int makeProd() {
    return (getVal<I, Vs>() * ...);
}

template <typename... Vs, std::size_t... Is>
constexpr auto zipHelper(std::index_sequence<Is...>)
    -> Vector<makeProd<Is, Vs...>()...>;

template <typename... Vs>
struct zip 
{
    static constexpr std::size_t size =
      vectorSize<std::tuple_element_t<0, std::tuple<Vs...>>>();
    static_assert(((vectorSize<Vs>() == size) && ...));

    using type = decltype(zipHelper<Vs...>(std::make_index_sequence<size>{}));
};

Demo

这是在 using partial template specializations 中实现此 zip 元函数的简单方法:

template <int...> struct Vector;

template <typename...>
struct zip;

template <int... Is>
struct zip<Vector<Is...>> {
    using type = Vector<Is...>;
};

template <int... Is, int... Js, typename... Vectors>
struct zip<Vector<Is...>, Vector<Js...>, Vectors...> {
    using type = typename zip<Vector<(Is * Js)...>, Vectors...>::type;
};

Godbolt.org