1

I have been working on a matrix class and I have recently learnt about passing const references to operator overloads so that I can have multiple of them on the same line. The problem I encountered is when defining a function for an operator overload, which takes a parameter by const reference, and then tries using another operator overload on that parameter. Some minimal code for this is shown below:

class Matrix
{
private:
    int col, row;
    typedef std::vector<double> Column;
    std::vector<Column> data;
public:
    Matrix(int rows, int columns) : col(columns), row(rows), data(rows, std::vector<double>(columns))
    {}

    Column& operator[](int i) //Operator overload to allow for use of Matrix[i][j]
    {
        return data[i];
    }

    Matrix& operator*(const Matrix& matrix2)
    {
        Matrix* matrix1 = new Matrix(row, col);
        matrix1->data = this->data;
        double tempValue = matrix1[0][0] * matrix2[0][0]; //Error here when accessing matrix2[0][0]

        return *matrix1;
    }
};

As you can see inside the operator* code I am trying to use the overload of the [] operator, which normally helps me use matrix[i][j] notation to enumerate through its data. This was working fine until I started using const Matrix& as a parameter to pass. Now when trying to access the indices of matrix2 it gives me this error:

no operator "[]" matches these operands

Does anyone know why this is happening or how to fix it ? I tried using const int& as a paramter for the operator[] overload but it did not seem to help. Accessing the indices of matrix1 seems to work fine otherwise.

2
  • 1
    Does your colum class implement an operator[] as well? And in operator*, do not new your return value, return a Matrix not a Matrix*! Avoid new/delete in C++ if you can if you need to allocate memory use std::make_unique (or std::make_shared) Commented Jul 2, 2022 at 9:42
  • 2
    I recommendd this canonical implementation operator overloading guide. Commented Jul 2, 2022 at 9:44

1 Answer 1

1

For starters matrix1 is a pointer but you need to apply the subscript operator for an object of the type Matrix.

matrix2 is a constant object but the subscript operator is not a constant member function.

You need to overload the operator [] as a constant member function

Column& operator[](int i) //Operator overload to allow for use of Matrix[i][j]
{
    return data[i];
}

const Column& operator[](int i) const //Operator overload to allow for use of Matrix[i][j]
{
    return data[i];
}

And the operator * should be declared like

Matrix operator*(const Matrix& matrix2) const
{
    Matrix matrix1(row, col);
    matrix1.data = this->data;
    double tempValue = matrix1[0][0] * matrix2[0][0];

    return matrix1;
}

though it is unclear what this statement

    double tempValue = matrix1[0][0] * matrix2[0][0];

is doing here.:)

Pay attention to that dynamically allocating an object in the operator * is a very bad idea.

Sign up to request clarification or add additional context in comments.

8 Comments

The problem I have here is that if I return matrix1 by value from the * operator, I won't be able to use several of these operators on one line without assigning to intermediate variables. For example, Matrix matrix = matrix1 * matrix2 * matrix3 will not work unless the * operator returns a matrix object by reference. The tempValue statement is not doing anything functional by the way, I stripped the function to only show where I am encountering an error, it actually loops around the indices and does standard matrix multiplication.
@AssistantToTheRegionalManager You are mistaken. You may bind a temporary object to a constant reference. If you will make the changes I showed you will be able to write for example Matrix m1( 2, 2 ); Matrix m2 = m1 * Matrix( 2, 2 ) * Matrix( 2, 2 );
@AssistantToTheRegionalManager References should be returned by assignment operators or by subscript operators at least that are not constant member functions.
@AssistantToTheRegionalManager You may bind a temporary object to a constant lvalue reference. So you may pass a temporary object to a function that has the corresponding parameter as a constant reference and the temporary object will be alive while the function is executed.
@AssistantToTheRegionalManager You need to have two overloaded operators as I showed in my answer.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.