I am building a matrix library and I am trying to use the policy-based design.
So my base classes are classes that provide a storage method and some
access functions.
I also have a function matrix which provides the mathematical functions.
This works great, but there is a major problem with the operator*
because of the return type. I will explain it with some code.
Base class that provides a stack storage :
template < typename T, unsigned int rows, unsigned int cols>
class denseStackMatrix {
public:
typedef T value_type;
private:
value_type grid[rows][cols];
const unsigned int rowSize;
const unsigned int colSize;
Then I have my matrix class which provides mathematical functionality :
template <typename MatrixContainer >
class matrix : public MatrixContainer {
public:
typedef MatrixContainer Mcontainer;
matrix<Mcontainer>& operator +(const matrix<Mcontainer>&);
matrix<Mcontainer>& operator *(const matrix<Mcontainer>&);
operator+ always works, operator* only works for square matrix.
So we still need one for all matrices. And that’s were it goes
wrong. I have already tried few things, but nothings works.
I look for something like this, with the help of c++0x (usage of
c++0x is not a requirement)
you shall notice the “???” 🙂
friend auto operator * (const matrix<T1>& matrix1, const matrix<T2>& matrix2)
-> decltype(matrix<???>);
An example of the problem
matrix<denseStackMatrix<int,3,2> > matrix1;
matrix<denseStackMatrix<int,2,4> > matrix2;
matrix<denseStackMatrix<int,3,4> > matrix3 = matrix1 * matrix2;
Here it will complain about the type, because it does not match any of the two parameter types. But the compiler needs to know the type at compile-time and I do not know how to provide it.
I know there are other options for the design, but I am really looking for a solution for this scenario..
Thank you !
Picking up on the idea of @hammar, but with partial specialization to allow the normal syntax like the question shows:
Edit: As you said in your comment, you can also use this to create a matrix that doesn’t use a MatrixContainer which has row and column size as template parameters:
Usage: