Search code examples
c++classoperator-overloadingconst-referencepass-by-const-reference

(C++) Using multiple operator overloads with const reference parameters


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.


Solution

  • 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.