Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ operator overload template with different arguments

I'm discovering C++ and I would like to create a mini mathematic Matrix librairy using templates.

Here, I want to overload the operator*.

If i describe a matrix like this: M(y, x) with M the matrix name, y and x the height and the width, a matrix multiplication should look like that:

M(a, b) * N(b, c) = R(a, c)

Currently I have this code:

template<unsigned int y, unsigned int x>
class Matrix
{
public:
    Matrix() { }
    ~Matrix() { }

    Matrix<y, x2>& operator*(const Matrix<y2, x2>& right)
    {
        // code...  
    }
private:
    std::array<std::array<double, x>, y>    m_values;
};

So I would like to be able to multiply two differents matrix like that:

Matrix<3, 4> m;
Matrix<4, 2> n;

// fill the matrix with values

Matrix<3, 2> o = m * n;

I've searched but I didn't find the answer to this question (maybe because I don't really know what I must search exactly).

Thanks for your help :)

like image 888
Ludonope Avatar asked Oct 17 '22 23:10

Ludonope


1 Answers

You need to make your operator* a template member function, something like so:

template <unsigned int y2, unsigned int x2>
Matrix<y, x2> operator*(const Matrix<y2, x2>& right)
{
    // code...  
}

Notice that the return type is no longer a reference, as operator* should return a new value -- if you like, you can define a complementary operator*= which modifies the LHS matrix in-place.

Another thing to notice is that matrix multiplication only makes sense if the dimensions of the matrices agree: that is, if the number of columns in the LHS matches the number of rows in the RHS. To enforce this, you could use a static_assert within your member function to make sure that the template parameters agree:

template <unsigned int y2, unsigned int x2>
Matrix<y, x2> operator*(const Matrix<y2, x2>& right)
{
    static_assert(y2 == x, "Matrix dimensions mismatched");
    // code...
}
like image 171
Tristan Brindle Avatar answered Oct 21 '22 04:10

Tristan Brindle