views:

67

answers:

2

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!

+6  A: 

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 McHenry
Wow, thanks for pointing that out for me. I actually went back a while ago and changed some of the functions and forgot that's what it was doing....lol. Well, I'm not sure this question was "StackOverflow worthy", but I'm not sure I would have noticed that anytime soon. Thanks!
John
Sometimes it just helps to have a second (or third, or fourth) set of eyes. :)
Tyler McHenry
+1  A: 

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!

Matthieu M.