Operator << in C++, "no operator found which takes right hand-operator" and "already has a body" error

Viewed 105

I have some code that is supposed to overload the operator << and be able to print a matrix object, but for some reason, it fails. Here's the code for it: (Matirx.h file)

#pragma once
#include <iostream>

using std::cout;
using std::endl;
using std::ostream;

template <int N=1, int M=1, class T = int>
class Matrix {
    int rows;
    int cols;
    T matrix[N][M];
public:

Matrix(T matrixVal = 0) :rows(N), cols(M) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            this->matrix[i][j] = matrixVal;
        }
    }
}

int getRows() { return rows; }
int getCols() { return cols; }
T** getMatrix() { return matrix; }

friend ostream& operator<<(ostream& out, const Matrix<>& mat) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            out << this->matrix[i][j];
            out << " ";
        }
        out << endl;
    }
    return out;
}

But when I add it, I get these errors:

Error C2084 function 'std::ostream &Matrix<4,4,int>::operator <<(std::ostream &,const Matrix<1,1,int> &)' already has a body

Error C2679 binary '<<': no operator found which takes a right-hand operand of type 'Matrix<4,4,int>' (or there is no acceptable conversion)

Error (active) E0349 no operator "<<" matches these operands

here's the main code:

#include "matrix.h"

template <int row, int col, typename T>
void printDiag(Matrix<row, col, T>& mat) {
    int number;
    T* diag = mat.getDiag(number);
    for (int i = 0; i < number; i++)
    {
    std::cout << diag[i] << " ";
   }
   std::cout << std::endl;
   delete[] diag;
}

int main() {

//freopen("output_matrix.txt", "w", stdout);

Matrix<4, 4> mat;
std::cout << mat << std::endl;

Matrix<4, 4> identity(1);
std::cout << identity << std::endl;

any help would be appreciated (:

1 Answers

Several problems with this. First in the declaration you have to specify the template arguments. As the whole class is templated, you don't need to explicitly add an other template before, but you need Matrix<N,M,T>.

The second issue is that you treat friend std::ostream& operator<<(...) as if it was a member function (using member variables and this). This is not the case. You might be declaring it inside the class, but it is definitely not part of the class. Where you use this-> use mat. and where you just use rows/cols use mat.rows/mat.cols.

I also had to modify the constructor a bit, but I still don't know why it was complaining.

Related