1

I am new to c++ and templates is definitely not friendly in syntax. Basically, here are some of the functions i've written, tested, and finished. Just one quick question, i've been trying for hours to write a non-member operator- overload for my matrix class and have been getting all types of syntax errors. So, where do I start?

Here is my myMatrix.h:

#ifndef MYMATRIX_H
#define MYMATRIX_H

#include <exception>
#include <vector>
#include <iostream>

using namespace std;

/* I'm using this matrix to store data */
template<typename T>
using twoD = std::vector<std::vector<T>>;

template<class T>
class Matrix{
    private:
        int rows;
        int cols;
        twoD<T> matrix;
    protected:
        void validSizeCheck(int rows, int cols);
    public:
        Matrix(int rows, int cols);
        Matrix(int rows, int cols, twoD<T> newMatrix);
        twoD<T> getMatrix();
        int getRows();
        int getCols();
        void printMatrix();
        void operator=(const Matrix<T> &);
        Matrix<T> &operator+=(const Matrix<T> &);
        Matrix<T> operator+(const Matrix<T> &);
        Matrix<T> operator*(const Matrix<T> &);
        Matrix<T> operator*(const T &);
};

Here is one of the thing I tried:

template <class T>
Matrix<T> operator-(const Matrix<T>& lhs,const Matrix<T>& rhs){
    if(lhs.rows != rhs.cols || lhs.rows != rhs.cols{
        throw exception();
    }
    Matrix tmp(lhs.rows, lhs.cols);
    for(int i = 0; i < lhs.rows; i++){
        for(int j = 0; j < cols; j++){
            tmp.matrix[i][j] = lhs.matrix[i][j]+rhs.matrix[i][j];
        }
    }  
    return tmp;    
}

Obviously that didn't work.. So what are the syntax that I should be following for this? Also, this might be a very dumb question but should the non-member function be in the header file or the .cpp file? So far, everything that I wrote has been in the .h file as they're all templates..

Any help would be greatly appreciated.

UPDATED: I finally got the code to works, for class & function declaration, I added this:

template<class T>
class Matrix{
    private:
        ...
    protected:
        ...
    public:
        ...
      template<class U>
      friend Matrix<U> operator-(const Matrix<U>& lhs, const Matrix<U>& rhs);        
};

Here is the function definition:

 template <class U>
 Matrix<U> operator-(const Matrix<U>& lhs,const Matrix<U>& rhs){
     if(lhs.rows != rhs.cols || lhs.rows != rhs.cols){
         throw exception();
     }
     Matrix<U> tmp(lhs.rows, lhs.cols);
     for(int i = 0; i < lhs.rows; i++){
         for(int j = 0; j < lhs.cols; j++){
             tmp.matrix[i][j] = lhs.matrix[i][j]-rhs.matrix[i][j];
         }
     }  
    return tmp;    
}

works perfect, no warning! Thanks for all the helps

Ben Voigt
  • 260,885
  • 36
  • 380
  • 671
Nam Vu
  • 1,304
  • 1
  • 8
  • 19
  • 1
    mismatched parentheses aren't helping anything... making me think this is not your real code – Ben Voigt Apr 29 '18 at 03:45
  • Where is the mismatched parenthesis? This is how I've been coding for as long as I can remember... Oh and I solved my question... – Nam Vu May 18 '18 at 13:02

2 Answers2

4

Members rows, cols are private. Non-class member operator must be a friend of a class. Declare it in the class:

friend Matrix<T> operator-<>(const Matrix<T>& lhs,const Matrix<T>& rhs);

Read this article for more info: Operator overloading : member function vs. non-member function?

Also, this might be a very dumb question, but should the non-member function be in the header file or the .cpp file? So far, everything that I wrote has been in the .h file as they're all templates.

You did it right, all templates must be in a header file. Here is more info: Why can templates only be implemented in the header file?

S.M.
  • 13,389
  • 7
  • 29
  • 39
  • Hi friend, thanks the quick answer. Unfortunately, I've tried that also, here is what I'm dealing with: – Nam Vu Apr 29 '18 at 04:11
  • myMatrix.h:34:78: warning: friend declaration ‘Matrix operator-(const Matrix&, const Matrix&)’ declares a non-template function [-Wnon-template-friend] friend Matrix operator-(const Matrix& lhs, const Matrix& rhs); ^ – Nam Vu Apr 29 '18 at 18:24
  • myMatrix.h:34:78: note: (if this is not what you intended, make sure the function template has already beendeclared and add <> after the function name here) myMatrix.h:34:78: warning: friend declaration ‘Matrix operator-(const Matrix&, const Matrix&)’ declares a non-template function [-Wnon-template-friend] friend Matrix operator-(const Matrix& lhs, const Matrix& rhs); ^ – Nam Vu Apr 29 '18 at 18:24
  • This is warnings only, I've updated the answer. Exactly what the compiler said. – S.M. Apr 29 '18 at 18:30
  • The problem is that I don't have an out out file when there are warnings like this.. code works fine when I comment out the non-member functions – Nam Vu May 02 '18 at 20:32
4

You need to use the template parameters again in the declaration of the temp variable inside:

template <class T>
Matrix<T> operator-(const Matrix<T>& lhs,const Matrix<T>& rhs){
    if(lhs.rows != rhs.cols || lhs.rows != rhs.cols{
        throw exception();
    }
    Matrix<T> tmp(lhs.rows, lhs.cols);
    for(int i = 0; i < lhs.rows; i++){
        for(int j = 0; j < cols; j++){
            tmp.matrix[i][j] = lhs.matrix[i][j]+rhs.matrix[i][j];
        }
    }  
    return tmp;    
}

(change is in Line 5: Matrix<T> tmp(lhs.rows, lhs.cols); )

Aganju
  • 5,994
  • 1
  • 9
  • 22