Reputation: 97
So I have this implementation of a tuple:
template<typename... TT>
struct Tuple {
enum{ size = sizeof...(TT) };
};
Now I'm trying to define a struct which gets a tuple of tuples to represent a 2D array in compile time. For example, usage:
template <int T>
struct Int {
enum { value = T };
};
typedef Matrix< Tuple<
Tuple < Int<1>, Int<2>, Int<3> >,
Tuple < Int<4>, Int<5>, Int<6> >
> > arr;
int width = arr::width; // width should be 3 as number of columns.
int length = arr::length; // length should be 2 as number of rows.
I have tried this approach:
template <typename TupleOfTuples>
struct Matrix;
template<typename ... TT>
struct Matrix<Tuple<Tuple<TT...>>> {
enum { width = Tuple<TT...>::size };
enum { length = Tuple<Tuple<TT...>>::size };
};
This seems to work ONLY when length = 1 (matrix of only one row).
For every other length I get the error message:
error: incomplete type 'arr {aka Matrix<Tuple<Tuple<Int<1>, Int<2>, Int<3> >, Tuple<Int<4>, Int<5>, Int<6> > > >}' used in nested name specifier
int width = arr::width;
I have also tried to mess around with the struct's declaration but nothing seemed to work!
How can I make this work?
Upvotes: 2
Views: 497
Reputation: 5157
What you did here can't work:
template<typename ... TT>
struct Matrix<Tuple<Tuple<TT...>>>
Because you create a specialization for Matrix
with a Tuple
that contains exactly one Tuple
. Therefore template deduction fails for this case.
You need to extract the first tuple from the nested tuple and take it's size. This assumes that all nested tuples have the same size:
template <class T1, class... T>
struct first
{
using type = T1;
};
template <int T>
struct Int
{
static constexpr auto value = T;
};
template<typename... TT>
struct Tuple
{
static constexpr auto size = sizeof...(TT);
};
template<typename... TT>
struct Matrix;
template<typename... TT>
struct Matrix<Tuple<TT...>>
{
static constexpr auto width = Tuple<TT...>::size;
static constexpr auto length = first<TT...>::type::size;
};
int main()
{
using arr = Matrix< Tuple<
Tuple < Int<1>, Int<2>, Int<3> >,
Tuple < Int<4>, Int<5>, Int<6> >>>;
std::cout << arr::width << arr::length << std::endl;
}
This outputs 23
Upvotes: 3