c++ global operator not playing well with template class

ok, i found some similar posts on stackoverflow, but I couldn't find any that pertained to my exact situation and I was confused with some of the answers given. Ok, so here is my problem:

I have a template matrix class as follows:

    template <typename T, size_t ROWS, size_t COLS>
    class Matrix
    {
 public:

  template<typename, size_t, size_t>
  friend class Matrix;

  Matrix( T init = T() )
   : _matrix(ROWS, vector<T>(COLS, init))
  {
   /*for( int i = 0; i < ROWS; i++ )
   {
    _matrix[i] = new vector<T>( COLS, init );
   }*/
  }

  Matrix<T, ROWS, COLS> & operator+=( const T & value )
  {
   for( vector<T>::size_type i = 0; i < this->_matrix.size(); i++ )
   {
    for( vector<T>::size_type j = 0; j < this->_matrix[i].size(); j++ )
    {
     this->_matrix[i][j] += value;
    }
   }
   return *this;
  }

 private:
  vector< vector<T> > _matrix;
    };

and I have the following global function template:

    template<typename T, size_t ROWS, size_t COLS>
    Matrix<T, ROWS, COLS> operator+( const Matrix<T, ROWS, COLS> & lhs,
        const Matrix<T, ROWS, COLS> & rhs )
    {
     Matrix<T, ROWS, COLS> returnValue = lhs;
     return returnValue += lhs;
    }

To me, this seems to be right. However, when I try to compile the code, I get the following error (thrown from the operator+ function):

binary '+=' : no operator found which takes a right-hand operand of type 'const matrix::Matrix<T,ROWS,COLS>' (or there is no acceptable conversion)

I can't figure out what to make of this. Any help if greatly appreciated!

Answers


Your operator+= here:

Matrix<T, ROWS, COLS> & operator+=( const T & value )

Defines a method of adding a T (a scalar) to a Matrix<T, ROWS, COLS>.

This statement:

return returnValue += lhs;

Attempts to add a Matrix<T, ROWS, COLS> (a matrix, the type of lhs) to a Matrix<T, ROWS, COLS>.

So the compiler is completely correct in saying that you have not defined that operation. You have an operator+= that adds a scalar to a matrix, but not an operator+= that adds a matrix to a matrix.


Tyler already answered, but I'd appreciate if you'd bear with me :)

There is a very nice Boost library (YABL ?) called Boost.Operators to relieve you of the tedium of writing all those things.

The idea is that:

  • + can be deduced from +=
  • != can be deduced from ==
  • <=, >= and > can be deduced from <
  • etc...

The library allow you to write one operator and will automatically add the others, thanks to some template magic. It allows symmetric ( T + T ) and asymmetric ( T + U ) operators.

Here it would give:

template <class T, size_t Rows, size_t Columns>
class Matrix: boost::addable< Matrix<T,Rows,Columns> > // private inheritance
{
public:
  Matrix& operator+=(const Matrix& rhs);
};

If you want to have multiple + operators, it's possible too

template <class T, size_t Rows, size_t Columns>
class Matrix: boost::addable < Matrix<T,Rows,Columns>
            , boost::addable < Matrix<T,Rows,Columns>, T
            > >
            // Note the nesting to avoid MI
{
public:
  Matrix& operator+=(const T& value);
  Matrix& operator+=(const Matrix& rhs);
};

Even better, in the asymmetric case, both T + U and U + T are generated as long as t += u makes sense!


Need Your Help

Generating HTML email body in ASP VB

asp-classic vbscript html-email

I want to send an HTML email where the body of the email is basically another HTML page. Is it possible to do that? The HTML page to send contains database records.