如何编写以下问题 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>{}));
};
这是在 c++14 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;
};
我是 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>{}));
};
这是在 c++14 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;
};