I'm trying to shape up my template skills (I know very little) by creating a library containing matrices and operations on those matrices. Basically, I want my matrix to be very strongly typed (datatype and size known at compile-time) and I also want to be able to automatically deduct the type of the transpose matrix.
template< typename TDataType, size_t rows, size_t cols > class MyMatrix
Matrices can be nested, so TDataType
can be an integral type, but also a MyMatrix<...>
by itself, causing the datatype for a transposed matrix to be not necessarily the same as the one of the original matrix, e.g:
Transpose( MyMatrix< MyMatrix< char, 2, 3 >, 4, 6 > ) ==> MyMatrix< MyMatrix< char, 3, 2 >, 6, 4 >
(the datatype of the outer matrix has changed)
My first attempt for transposed-type-deduction was:
template< typename TDataType >
struct Transpose
{
typedef TDataType type;
};
template<>
struct Transpose< MyMatrix<TDataType, rows, cols> >
{
typedef MyMatrix<typename Transpose<TDataType>::type, cols, rows> type;
};
I have found no way of doing this because I can't seem to specialize the Transpose-template with MyMatrix (TDataType unknown and similar errors).
The only compilable solution I've come up with (I don't even know if it works yet) is this:
template< typename TMatrixType, typename TDataType, size_t rows, size_t cols >
struct Transpose
{
typedef TMatrixType type;
};
template< typename TDataType, size_t rows, size_t cols >
struct Transpose< MyMatrix<TDataType, rows, cols>, TDataType, rows, cols >
{
typedef MyMatrix< typename Transpose<TDataType,TDataType,rows,cols>::type, cols, rows > type;
};
I believe I am making things too complicated; is there an easier solution to achieve what I want?
An answer to the answers to my question (I posted the question without an account, so I don't have enough rep to do things the normal way). Thanks a lot already!
@Bo Persson @Will A : I do not intend to use this as a general purpose matrix library, I want to perform operations on matrices of specific (known beforehand) sizes and want to see where I can get by using this approach. It may allow me to optimize memory-layout for matrices (e.g. align row-vectors on 32-byte boundaries) and do other sorts of funky stuff. I expect to shoot myself in the foot an awful lot of times by doing this, but the main thing I'm trying to get here is experience and find out what works and what doesn't (and what is hard to do and what isn't).
@Bo Perrson : I know why the first version doesn't compile, but I was wondering if there was a simpler version of my second try that could work. Main problem is that MyMatrix is a class template itself and I need to get the template arguments of it somehow to the Transpose-struct.
@VJo : I don' t think that would work. If T is a MyMatrix<..> itself then the transpose matrix should have Transpose<T>
as a datatype, not T itself. For all basic types (char, int, double...), this is of course correct and way simpler.