глобальный оператор c ++ плохо играет с классом шаблона - PullRequest
2 голосов
/ 31 марта 2010

Хорошо, я нашел несколько похожих сообщений в stackoverflow, но я не смог найти ни одной, относящейся к моей конкретной ситуации, и меня смутили некоторые из приведенных ответов. Итак, вот моя проблема:

У меня есть шаблон матрицы класса следующим образом:

    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;
    };

и у меня есть следующий шаблон глобальной функции:

    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;
    }

Мне кажется, это правильно. Однако, когда я пытаюсь скомпилировать код, я получаю следующую ошибку (выдается из оператора + функция):

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

Я не могу понять, что с этим делать. Любая помощь, если высоко ценится!

Ответы [ 2 ]

6 голосов
/ 31 марта 2010

Ваш operator+= здесь:

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

Определяет метод добавления T (скаляр) к Matrix<T, ROWS, COLS>.

Это утверждение:

return returnValue += lhs;

Пытается добавить Matrix<T, ROWS, COLS> (матрицу, тип lhs) к Matrix<T, ROWS, COLS>.

Таким образом, компилятор совершенно прав, говоря, что вы не определили эту операцию. У вас есть operator+=, который добавляет скаляр к матрице, но не operator+=, который добавляет матрицу к матрице.

1 голос
/ 31 марта 2010

Tyler уже ответил, но я был бы признателен, если бы вы терпели меня:)

Существует очень хорошая библиотека Boost (YABL?), Которая называется Boost.Operators , чтобы избавить вас от утомительного труда написать все эти вещи.

Идея в том, что:

  • + можно вывести из +=
  • != можно вывести из ==
  • <=, >= и > могут быть выведены из <
  • и т.д ...

Библиотека позволяет написать один оператор и автоматически добавит других, благодаря некоторой магии шаблонов. Он допускает симметричные (T + T) и асимметричные (T + U) операторы.

Вот это даст:

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);
};

Если вы хотите иметь несколько + операторов, это тоже возможно

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);
};

Еще лучше, в асимметричном случае генерируются и T + U, и U + T, пока t += u имеет смысл!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...