So I have a matrix class that must run on a unix/linux server. The main is a test file that is provided by the instructor. When I compile my code in visual studio it works fine except for test 8 because I can't figure out how to return a print line for incompatible matrix multiplication. When I compile the code on the server it gives me error: no match for âoperator<<â in âstd::operator<< for both test 7 and 8. For test 7 I assume the compiler is having trouble identifying that there are 2 calls of transpose being called. Any help is greatly appreciated, thank you.

#include <iostream>
#include "Matrix.h"

using namespace std;




int main(){
	 
    int i, j ;
    int rows, cols;
    
    // Test1: the default class constructor
    Matrix bigMatrix;
    cout << "Test 1: bigMatrix = \n" << bigMatrix;
    
    // Test2: the other class constructor
    Matrix dMatrix(4,5);
     
    rows = dMatrix.num_rows();
    cols = dMatrix.num_cols();
    
    // put some numbers into the matrix 
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++)
            //if(i == j)
                dMatrix.set_element(i, j, i*1.0 + j*0.1);
    }
    
    cout << "\nTest 2: dMatrix = \n" << dMatrix;
    
    // get_element 
    cout << "\nTest 3: dMatrix[2][3] = " << dMatrix.get_element(2,3) << endl;
    cout << "Test 3: dMatrix[3][3] = " << dMatrix.get_element(3,3) << endl;
    
    
    // set_element
    dMatrix.set_element(2, 3, 0.0);
    cout << "\nTest 4: the modified dMatrix = \n" << dMatrix;
    
    // product between a matrix and a scalar
    ElementType scal = 2.0;
    Matrix res1 = dMatrix*scal;
    cout << "\nTest 5: res1 = dMatrix * " << scal << " =\n" << res1;
   
    // transpose of a matrix
    Matrix res2 = res1.transpose();
    cout << "\nTest 6: res2 = res1 ^ T = \n" << res2;
    
    // the transpose of the transpose of any matrix should be the matrix itself
    cout << "\nTest 7: res1 ^ T ^ T = \n" << res1.transpose().transpose();
    
    // multiplying two incompatible matrices
    cout << "\nTest 8: res1 * res1 = " << res1 * res1;
    
	
    // multiplying two compatible matrices
    Matrix res3 = res1 * res2;
    cout << "\nTest 9: res1 * res 2 = \n" << res3; 
   
	system("pause");

	return 0;

}
#include "Matrix.h"
using namespace std;



//Default Constructor
Matrix::Matrix()
	:numRows(MAX), numColumns(MAX)
{
	//intialize a 20x20 matrix to 0.0
	initializeArray(MAX,MAX);

}

//Constructor
Matrix::Matrix(int rows, int columns)
	:numRows(rows), numColumns(columns)
	
{

	//error checking of input row/colum numbers are valid-*******
	if((numRows < 0) || (numColumns < 0)){
		cout << "Improper row or column.\n";
		numRows = 0;
		numColumns = 0;
		system("pause");
	}
	else if((numRows > MAX) || (numColumns > MAX)){
		cout << "Improper row or column.\n";
		numRows = 0;
		numColumns = 0;
		system("pause");
	}

	//intialize specific matrix(rows,columns) to 0.0
	initializeArray(numRows, numColumns);
}

//Destructor
Matrix::~Matrix()
{

}

//Initialize Array [rows][columns] to 0.0 
void Matrix::initializeArray(int numRows, int numColumns)
{
	for(int i = 0; i < numRows; i++)
		for(int j = 0; j < numColumns; j++)
			myArray[i][j] = 0.0;
}

//return number of rows
int Matrix::num_rows()
{
	return numRows;
}

//return number of columns
int Matrix::num_cols()
{
	return numColumns;
}

//return the value of an element in a specified row/columns
ElementType Matrix::get_element(int row, int col)
{
	return myArray[row][col];
}

//set the value of an element in a specified row/columns
void Matrix::set_element(int row, int col, double new_value)
{
	myArray[row][col] = new_value;
}

//transpose matrix 
Matrix Matrix::transpose()
{
	Matrix temp1(numColumns,numRows);

	for(int i = 0; i < temp1.num_cols(); i++){
		for(int j = 0; j < temp1.num_rows(); j++){
			temp1.myArray[j][i] = myArray[i][j];
		}
	}

	return(temp1);
}

//Product operator overload
//allows Matrix * scaler
Matrix operator* (ElementType scalar, Matrix &aMatrix){
	int numRows = aMatrix.num_rows();
	int numColumns = aMatrix.num_cols();

    Matrix temp1(numRows, numColumns);
 
    for(int i = 0; i < temp1.num_rows(); i++){
		for(int j = 0; j < temp1.num_cols(); j++){
			temp1.myArray[i][j] = scalar * aMatrix.get_element(i,j);
		}
	}
	return (temp1);
}

Matrix operator* (Matrix &aMatrix, ElementType scalar){
	
	int numRows = aMatrix.num_rows();
	int numColumns = aMatrix.num_cols();

    Matrix temp1(numRows, numColumns);
 
    for(int i = 0; i < temp1.num_rows(); i++){
		for(int j = 0; j < temp1.num_cols(); j++){
			temp1.myArray[i][j] = aMatrix.get_element(i,j) * scalar ;
		}
	}
	return (temp1);

}

//Matrix multiplication overloader
Matrix operator* (Matrix &aMatrix, Matrix &bMatrix){

	int rows2 = aMatrix.num_rows();
	int columns2 = bMatrix.num_cols();

	Matrix temp2(rows2,columns2);

	//if(aMatrix.num_cols()  == bMatrix.num_rows()){	
		for(int i = 0; i < rows2; i++){
			for(int j = 0; j < columns2; j++){
				for(int k = 0; k < aMatrix.num_cols(); k++){
					temp2.myArray[i][j] += aMatrix.get_element(i, k) * bMatrix.get_element(k,j);
				}
			}
			
		}
		return (temp2);
	
}

//ostream overloader
ostream &operator<< (ostream &out, Matrix &myMatrix)
{
	for(int i=0; i < myMatrix.num_rows(); i++){
		for (int j=0; j< myMatrix.num_cols(); j++){
			out.width(3);
			out << myMatrix.get_element(i,j) << "  ";
		}
		out << endl;
	}
	out << endl;
	return (out);
}
#ifndef MATRIX_H
#define MATRIX_H

#include <cstdlib>
#include <iostream>
#include <assert.h>
#include <string>
#define MAX 20
#define ElementType double
#pragma once

using std::ostream;

class Matrix
{
public:
	friend Matrix operator * (Matrix &aMatrix, Matrix &bMatrix);

	//product overloader to allow scaler * matrix 
	friend Matrix operator * (Matrix &aMatrix, ElementType scalar);
    friend Matrix operator * (ElementType scalar, Matrix &aMatrix);
	friend ostream &operator<< (ostream &out, Matrix &myMatrix);

	Matrix();
	Matrix(int numRows, int numColumns);
	~Matrix();

	void initializeArray(int numRows, int numColumns);

	//get number of rows
	int num_rows();
	//get number of columns
	int num_cols();

	//get element in  a matrix
	ElementType get_element(int row, int col);
	//set element in a matrix
	void set_element(int row, int col, double new_value);

	//transpose function
	Matrix transpose();
	
private:
	ElementType myArray[MAX][MAX];
	int numRows;
	int numColumns;
	int row;
	int col;
};

#endif

The overloaded<< operator only allows non-const references, which excludes temporaries like the ones returned by transpose() or calculated with the overloaded operator*. You should change it to expect a reference to const instead as you don't make any changes to the object's state:

ostream &operator<< (ostream &out, Matrix const &myMatrix)
{
	for(int i=0; i < myMatrix.num_rows(); i++){
		for (int j=0; j< myMatrix.num_cols(); j++){
			out.width(3);
			out << myMatrix.get_element(i,j) << "  ";
		}
		out << endl;
	}
	out << endl;
	return (out);
}

That also requires the called methods of num_rows(), num_cols(), and get_elements() to be declared as const methods, but that's how they should be defined anyway to maintain const correctness:

int Matrix::num_rows() const
{
	return numRows;
}

int Matrix::num_cols() const
{
	return numColumns;
}

ElementType Matrix::get_element(int row, int col) const
{
	return myArray[row][col];
}

Thanks so much, everything works perfectly fine now. Its hard to believe that I took those const's out before and forgot to put them back in lol. Thanks again.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.