I am practicing on template meta-programming and wanted to implement a simple trivial meta-function. I wonder how one can implement zip functionality on custom vectors. What I have in my mind is as follows:
Here is how the zip operation for this custom vector look like:
Inputs:
Vector<1, 2, 3>
Vector<2, 3, 4>
Vector<3, 4, 5>
Output:
Vector<6, 24, 60>
I believe my Vector
class should be declared like:
template<int... vals>
struct Vector;
zip meta-function should have the signature:
template<typename... Vectors>
struct zip
{
///
}
I cannot figure out how to multiply values in the input vectors that happen to be in the same index via template meta-programming?
CodePudding user response:
You can partially specialise zip
in order to expose the template parameters of the Vector
s you pass.
template<typename...>
struct zip;
template<int... Us, int... Vs, typename... Tail>
struct zip<Vector<Us...>, Vector<Vs...>, Tail...> {
using type = zip<Vector<(Us * Vs)...>, Tail...>::type;
};
template<typename T>
struct zip<T> {
using type = T;
};
static_assert(std::is_same<zip<Vector<2, 4, 6>,
Vector<1, 2, 3>,
Vector<3, 6, 9>>::type,
/* == */ Vector<6, 48, 162>>::value);
CodePudding user response:
template<int... vals>
struct Vector;
template<typename...Ts>
struct zip;
template<int...vals>
struct zip<Vector<vals...>>
{
using type = Vector<vals...>;
};
template<int...Avals, int...Bvals, typename...Ts>
struct zip<Vector<Avals...>, Vector<Bvals...>, Ts...>
{
using type = typename zip<Vector<(Avals*Bvals)...>, Ts...>::type;
};
template<typename...Ts>
using zip_t = typename zip<Ts...>::type;
https://godbolt.org/z/8KjMj69Y6
CodePudding user response:
By taking the heads off and zipping those:-
template <typename...Ts>
struct Vector
{
using type = Vector <Ts...>;
};
// concatenate adds an item to a list
template <class ...>
struct con;
template <class T, class...Ts>
struct con <T, Vector<Ts...>>:
Vector <T, Ts...>
{};
template <class...>
struct zip;
template <class L1>
struct zip <L1, Vector <>>:
Vector <>
{};
template <class L2>
struct zip <Vector <>, L2>:
Vector <>
{};
template <class H1, class...T1s, class H2, class...T2s>
struct zip <Vector <H1, T1s...>, Vector <H2, T2s...>>:
con
<
Vector <H1, H2>,
typename zip <Vector <T1s...>, Vector <T2s...>>::type
>
{};