Templates - Defining and Implementing Operator Overloading

Hey guys, I'm struggling a bit to combine templates and operator overloading.

I'm writing a program that will be able to perform various matrix arithmetic at the end. However I'm stuck at the overloaded << and >> functions. I've defined them as I'm used to, without working with templates, however they are incorrect as I have defined them, and I'm not sure how to fix it.

I want to overload the stream insertion operator >> to read matrix data from either the keyboard or a file stream. I want to use >> to input a 3 x 3 matrix stored in a text file in the following format:
2 4 3
5 2 3
7 1 0
And similarly I want to overload the stream extraction operator << to output a matrix to the screen or file in the following format:
3 2 -1
1 -1 2
2 3 -1

As I am very new to these concepts I'm not sure how to do this at all, any help will be greatly appreciated!!

Here is my work so far:

matrix.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#ifndef MATRIX_H
#define MATRIX_H

#include <cassert>
#include <iostream>

using namespace std;

template <class T> class Matrix;

template <class T>
class Matrix
{
        //These declarations are incorrect, don't know how to fix or implement:
	friend istream& operator>>(istream&, Matrix<T>&);
	friend ostream& operator<<(ostream&, const Matrix<T>&);
  
public:
	//Constructor
	Matrix(unsigned r, unsigned c);
	//Copy Constructor
	Matrix(const Matrix<T>& rhs);
	//Destructor
	~Matrix();
	//Overloaded = operator signature
	Matrix operator=(const Matrix<T>& m) const;

	// Getters:
	unsigned getRows() const; // Return number of rows
	unsigned getCols() const; // Return number of columns

private:
	//Default constructor
	Matrix();

	T ** matrix; // matrix array
	unsigned rows; // # rows
	unsigned cols; // # columns
};
#endif 


matrix.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "matrix.h"

template <class T>
Matrix<T>::Matrix()
{

}

template <class T>
Matrix<T>::Matrix(unsigned r, unsigned c)
{
    rows = r;
    cols = c;

    matrix = new T*[rows];
    for (unsigned int i = 0; i < rows; ++i)
    {
	matrix[i] = new T[cols];
    }
    
    for (unsigned int i = 0; i < rows; i++)
    {
	for (unsigned int j = 0; j < rows; j++)
	{
	    matrix[i][j] = 0;
	}
    }
}

template <class T>
Matrix<T>::Matrix(const Matrix<T>& rhs)
{
    rows = rhs.rows;
    cols = rhs.cols;
    
    matrix = new T*[rhs.rows];
    for (unsigned int i = 0; i < rows; ++i)
    {
	matrix[i] = new T[cols];
    }
    
    for (unsigned int i = 0; i < rows; i++)
    {
	for (unsigned int j = 0; j < rows; j++)
	{
	    matrix[i][j] = rhs.matrix[i][j];
	}
    }

    return this;
}

template <class T>
Matrix<T>::~Matrix()
{
    rows = 0;
    cols = 0;
    
    for (unsigned int i = 0; i < rows; i++)
    {
	for (unsigned int j = 0; j < rows; j++)
	{
	    delete [] matrix[i];
	}
    }
    delete [] matrix; 
}

template <class T>
Matrix<T> Matrix<T>::operator=(const Matrix<T>& m) const
{
    if (this != &m)
    {
	for (unsigned int i = 0; i < rows; i++)
	{
	    for (unsigned int j = 0; j < rows; j++)
	    {
		matrix[i][j] = m.matrix[i][j];
	    }
	}
    }
}

template <class T>
unsigned int Matrix<T>::getRows() const
{
    return rows;
}

template <class T>
unsigned int Matrix<T>::getCols() const
{
    return cols;
}

And the operators?
I've figured out that the operators are defined as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef MATRIX_H
#define MATRIX_H

#include <cassert>
#include <iostream>
#include <iomanip>

using namespace std;

template <class T> class Matrix;
template <class T> istream& operator>> (istream& is, Matrix<T>& m);
template <class T> ostream& operator<< (ostream& is, const Matrix<T>& m);

template <class T>
class Matrix
{
	//Overloaded << and >> operators
	friend istream& operator>> <>(istream& is, Matrix<T>& m);
	friend ostream& operator<< <>(ostream& os, const Matrix<T>& m);
  
public:
	...

private:
	...
};
#endif 


However, I'm unsure about the implementation, I have been unable to do it yet.
Last edited on
> As I am very new to these concepts I'm not sure how to do this at all, any help will be greatly appreciated
> //These declarations are incorrect, don't know how to fix or implement:

Declaring template friends is tricky; http://www.parashift.com/c++-faq-lite/template-friends.html

The simplest solution is to define the friend functions inline (within the class definition).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template <class T>
class Matrix
{
	friend istream& operator>> ( istream& stm, Matrix<T>& m )
	{
	    for( unsigned int r = 0 ; r < m.rows ; ++r )
                for( unsigned int c = 0 ; c < m.cols ; ++c ) stm >> m[r][c] ;
            return stm ;
	}

	friend ostream& operator<<( ostream& stm , const Matrix<T>& m )
	{
	    for( unsigned int r = 0 ; r < m.rows ; ++r )
            {
                for( unsigned int c = 0 ; c < m.cols ; ++c ) stm << m[r][c] << ' '  ;
                stm << '\n' ;
            }
            return stm ;
	}


public:
	// ...
};


Move the contents of matrix.cpp to the header file; the compiler needs to see the template definitions.

EDIT:
> I've figured out that the operators are defined as follows:

Well done!
Last edited on
@JLBorges, thank you very much for your help and info! That helped me a lot.

> Well done!

Thank you! :D
Last edited on
Topic archived. No new replies allowed.