1

I was creating a matrix class with overloaded operators in C++, I overloaded operators, << (output, with the ostream library), operator + that adds to matrices, operator = that's is used to assign one matrix to another. The problem is that when I use

cout<<m1+m2<<endl;

I get an error

E0349: No operator << matches these operands type are: std::ostream << Matrix

But if i do the following:

Matrix m = m1 + m2;
cout<<m<<endl;

it works perfect. Here is the << operator:

ostream& operator<< (ostream &os,const Matrix& m)
{
    if (m.isValid())
    {
        os << '|';
        for (int i = 0; i < m.getRows(); i++)
        {
            for (int j = 0; j < m.getCols(); j++)
            {
                os << m.getMatrix()[i][j];
                if (j < m.getCols() - 1)
                {
                    os << ',';
                }
            }
            os << '|';
        }
    }
    else
    {
        os << "invalid matrix!";
    }
    return os;
}

The + operator:

Matrix Matrix::operator+ (Matrix &m)
{
    Matrix* answer = new Matrix(m); //allocating space
    if (valid && m.valid)//if they are both valid
    {
        if (colNum == m.colNum&&rowNum == m.rowNum) //if are from same size
        {
            answer->valid = true; //valid set to be true
            for (int i = 0; i < rowNum; i++) //going over the matrix
            {
                for (int j = 0; j < colNum; j++)
                {
                    answer->matrix[i][j] += matrix[i][j]; //adding data
                }
            }
        }
        else
        {
            //clearing data
            delete answer;
            answer = new Matrix();
        }
    }
    else
    {
        //clearing data
        delete answer;
        answer = new Matrix();
    }
    return *answer;
}

And the = operator:

Matrix Matrix::operator= (Matrix &m)
{
    int rows = m.rowNum; //putting cols and rows from the data
    int cols = m.colNum;
    if (m.valid)
    {
        matrix = new int*[rows]; //defining the matrix - first allocatin space for rows
        for (int i = 0; i < rows; i++) //now allocating space for cols
        {
            matrix[i] = new int[cols];
        }
        for (int i = 0; i < rows; i++) //now going over the matrix and putting the data in
        {
            for (int j = 0; j < cols; j++)
            {
                matrix[i][j] = m.matrix[i][j];
            }
        }
    }
    //putting the rows and cols data
    rowNum = m.rowNum;
    colNum = m.colNum;
    valid = m.valid; //setting to the right valid type
    return *this;
}

and the class variables:

class Matrix
{
private:
    bool valid;
    int** matrix;
    int rowNum;
    int colNum;

There is a copy constructor a string constructor and a constructor that gets string input according to an algorithm and transforms it to a matrix.

Tal Sokolinsky
  • 88
  • 1
  • 14
  • Unrelated to your question, but your `operator+` function have a memory leak. – Some programmer dude May 24 '18 at 11:52
  • 1
    More related to your question, I suggest you read e.g. [this canonical implementation reference](http://en.cppreference.com/w/cpp/language/operators#Canonical_implementations). I suggest it because, for one thing, your copy-assignment operator is not quite correct. Also, if you read the linked reference thoroughly you will see what arguments the `operator<<` function should take. Hint: A non-constant reference can not be bound to non-lvalues. – Some programmer dude May 24 '18 at 11:53

1 Answers1

7

You are actually faced with the fact that you Can't pass temporary object as reference (the link is to another question here on StackOverflow).

The solution in your case should be to replace:

ostream& operator<< (ostream &os,Matrix& m)

with:

ostream& operator<< (ostream &os,const Matrix& m)

as the overloaded operator signature. You currently expects an lvalue reference, In the case of

Matrix m = m1 + m2;
cout << m << endl;

that is what you're calling the function with m - a named variable and will outlive the execution of the command. In the failing case, you're calling the function with m1+m2 - the result of a plus operation, which is a temporary object. It just doesn't match your overload.

By the way - this change also makes sense because you're not modifying the matrix as you print it - you treat it as const.

einpoklum
  • 118,144
  • 57
  • 340
  • 684