I am writing matrix classes. Take a look at this definition:
template <typename T, unsigned int dimension_x, unsigned int dimension_y>
class generic_matrix
{
...
generic_matrix<T, dimension_x - 1, dimension_y - 1>
minor(unsigned int x, unsigned int y) const
{ ... }
...
}
template <typename T, unsigned int dimension>
class generic_square_matrix : public generic_matrix<T, dimension, dimension>
{
...
generic_square_matrix(const generic_matrix<T, dimension, dimension>& other)
{ ... }
...
void foo();
}
The generic_square_matrix class provides additional functions like matrix multiplication.
Doing this is no problem:
generic_square_matrix<T, 4> m = generic_matrix<T, 4, 4>();
It is possible to assign any square matrix to M, even though the type is not generic_square_matrix, due to the constructor. This is possible because the data does not change across children, only the supported functions. This is also possible:
generic_square_matrix<T, 4> m = generic_square_matrix<T, 5>().minor(1,1);
Same conversion applies here. But now comes the problem:
generic_square_matrix<T, 4>().minor(1,1).foo(); //problem, foo is not in generic_matrix<T, 3, 3>
To solve this I would like generic_square_matrix::minor to return a generic_square_matrix instead of a generic_matrix. The only possible way to do this, I think is to use template specialisation. But since a specialisation is basically treated like a separate class, I have to redefine all functions. I cannot call the function of the non-specialised class as you would do with a derived class, so I have to copy the entire function.
This is not a very nice generic-programming solution, and a lot of work.
C++ almost has a solution for my problem: a virtual function of a derived class, can return a pointer or reference to a different class than the base class returns, if this class is derived from the class that the base class returns. generic_square_matrix is derived from generic_matrix, but the function does not return a pointer nor reference, so this doesn't apply here.
Is there a solution to this problem (possibly involving an entirely other structure; my only requirements are that the dimensions are a template parameter and that square matrices can have additional functionality).
Thanks in advance,
Ruud