I'm writing a Matrix template class that can support both row and column major storage. Ideally I'd like to specialise only the methods that are affected by the storage format. However, when I try to specialise a method (as below) I get nothing but error messages.
enum MatrixStorage
{
ColumnMajor,
RowMajor
};
template< typename T,
unsigned rows,
unsigned columns,
MatrixStorage storage = ColumnMajor >
class Matrix
{
public:
T & operator () ( unsigned const & row, unsigned const & column );
};
template< typename T,
unsigned rows,
unsigned columns >
T & Matrix< T, rows, columns, ColumnMajor >::
operator () ( unsigned const & row, unsigned const & column )
{
return elements[ ( row + ( rows * column ) ) % ( rows * columns ) ];
}
template< typename T,
unsigned rows,
unsigned columns >
T & Matrix< T, rows, columns, RowMajor >::
operator () ( unsigned const & row, unsigned const & column )
{
return elements[ ( ( row * columns ) + column ) % ( rows * columns ) ];
}
Error output:
error C3860: template argument list following class template name must list parameters in the order used in template parameter list
error C2976: 'maths::Matrix<T,rows,columns,storage>' : too few template arguments
error C3860: template argument list following class template name must list parameters in the order used in template parameter list
Following the examples given in other questions it looks like the syntax is correct. Still, the only way I can get this to work is by specialising the class itself (as below), but this means duplicating all of the methods that aren't dependent on the storage format.
enum MatrixStorage
{
ColumnMajor,
RowMajor
};
template< typename T,
unsigned rows,
unsigned columns,
MatrixStorage storage = ColumnMajor >
class Matrix;
template< typename T,
unsigned rows,
unsigned columns >
class Matrix< T, rows, columns, ColumnMajor >
{
T & operator () ( unsigned const & row, unsigned const & column );
};
template< typename T,
unsigned rows,
unsigned columns >
class Matrix< T, rows, columns, RowMajor >
{
T & operator () ( unsigned const & row, unsigned const & column );
};