I have a Matrix class
template<typename Type, size_t Rows, size_t Columns> class Matrix
{
public:
Type Entries[Rows][Columns];
// Operators, etc.
};
I then needed to make specializations of this class (for square matrices, etc.), which means I needed to rewrite the whole class implementation for each specialization. I then proceeded to think of methods that will avoid code duplication.
First idea that came to mind was to define the specialized functions in the base template but delete them so they can't be used in the base template and define specializations outside the class.
// Inside class definition
auto GetDeterminant() const -> T = delete;
// Outside class definition
template<typename Type, size_t Size> Matrix<T, Size, Size>::GetDeterminant() const -> T
{
// Implementation
}
But then, after encountering some errors, I learned that partially specializing function templates is not allowed. So I tried these methods
Method 1:
template<typename Derived, typename Type, size_t Rows, size_t Columns> class MatrixBase
{
public:
T Entries[Row][Columns];
// Operators, etc.
}
template<typename Type, size_t Rows, size_t Columns> class Matrix : public MatrixBase<Matrix<Type, Rows, Columns>, Rows, Columns>
{
// General MxN matrix stuff
}
template<typename Type, size_t Size> class Matrix<T, Size, Size> : public MatrixBase<Matrix<T, Size, Size>, Size, Size>
{
public:
// Specific MxM matrix stuff
}
Here I implemented CRTP as seen on another question, however I feel that the abstraction is somewhat unneeded and though that there is probably a better way. So I came up with another method.
Method 2:
template<typename T, size_t Rows, size_t Columns> class Matrix
{
public:
T Entries[Rows][Columns]
auto GetDeterminant() const -> T
{
static_assert(Rows == Columns);
// Some computations
}
}
Which seems fine, if someone tries to use this on a non-square matrix they get a compile-time error.
Question:
Is there a way of solving this by using only templates? or should I just stick with one of these methods?