Overloading confusion

From: Zac Bond (zwb2_at_cwru.edu)
Date: 02/28/05


Date: Sun, 27 Feb 2005 19:03:16 -0500

I am building overloads to create a matrix class, but I can't get them
to work properly. Here is what I have:

A matrix is a collection of rows, which in turn are collections of
doubles.

// Assignment for matrix; assumes the same size!
Matrix& Matrix::operator=(Matrix& m)
{
    // Copy rows and cols
    for (int i = 0; i < m.rows(); i++)
        for (int j = 0; j < m.cols(); j++)
            rvec[i][j] = m[i][j];
    return *this;
}

Row& Matrix::operator[](int r)
{
    return rvec[r]; // a row is actually a wrapper for vector<float>.
}

Matrix operator*(const double a, Matrix& m)
{
    Matrix r(m.rows(), m.cols());
    for (int i = 0; i < r.rows(); i++)
    for (int j = 0; j < r.cols(); j++)
    r[i][j] = i * m[i][j];
    return r;
}

This looks fine to me, but I get the following compile error when I
try to do:
mx1 = 3 * mx2;
where mx1 and mx2 are 3-by-3 matrices:
"initialization of non-const reference type "class Matrix &" from
rvalue of type "Matrix" in passing argument one of
"Matrix::operator=(Matrix)."

If I change the Matrix& parameter into Matrix, things work fine. Why
did the instructions I read on overloading tell me to do it as above?
Are they wrong? In fact, I discovered I needed to go drop ALL the
references to get nested operations to work. Is dropping the
references going to give me any bad side effects?

Also, why did they have all of the parameters const? In order to be
able to do assignments like:
a[1][2] = 3;
I need to have Matrix::operator[] be a non-const function, and in
order to use expressions like that in my definitions for the OTHER
functions, I consequently must make their parameters non-const as
well. Yet the example I read didn't remove those consts even though
my complier will not run if I don't. Am I missing something?

Thanks,
-Zac