2014-01-16 2 views
1

Я пишу 2D-матричный шаблон для изучения шаблонов и некоторых функций C++ 11.Перегруженный шаблонный двоичный оператор с шаблоном *

Написал заголовок:

template <class T, unsigned int Rows, unsigned int Columns> 
class Matrix2D 
{ 
private: 
    array<array<T,Columns>, Rows> m_Matrix; 

public: 
    Matrix2D() {} 

    array<T,Columns>& operator[](unsigned int row)  { return m_Matrix[row]; } ; 
    const array<T,Columns>& operator[](unsigned int row) const { return m_Matrix[row]; } ; 

    friend Matrix2D operator+ <> (const Matrix2D &lhs, const Matrix2D &rhs); 
    friend Matrix2D operator* <> (const Matrix2D &lhs, const Matrix2D &rhs); 
}; 

operator+ работает отлично - у меня есть реализация, компилирует, ссылки, и шагнул с помощью отладчика.

Проблема с operator*, для которого я получаю ошибку компиляции

1>...\matrix2d.h(18): error C2143: syntax error : missing ';' before '<' 
1>...\matrix2d.h(19) : see reference to class template instantiation 'Matrix2D<T,Rows,Columns>' being compiled 

Там нет строки кода пытается использовать оператор, так что это само определение, которое не так, я просто не понимаю, почему ,

Может ли кто-нибудь помочь?

EDIT: (добавил от комментариев)

template <class T, unsigned int Rows, unsigned int Columns> 
Matrix2D<T, Rows, Columns> operator+ (const Matrix2D<T, Rows, Columns> &lhs, const Matrix2D<T, Rows, Columns> &rhs) 
{ 
    Matrix2D<T, Rows, Columns> addResult; 
    for (unsigned int i = 0; i < Rows; i++) 
     for (unsigned int j = 0; j < Columns; j++) 
      addResult[i][j] = lhs[i][j] + rhs[i][j]; 
    return addResult; 
} 

template <class T, unsigned int Rows, unsigned int Columns> 
Matrix2D<T, Rows, Columns> operator* (const Matrix2D<T, lRows, lColumns> &lhs, const Matrix2D<T, rRows, rColumns> &rhs) 
{ 
    Matrix2D<T, lRows, rColumns> mulResult; 

    for(unsigned int i = 0; i < lRows; i++) 
     for(unsigned int j = 0; j < rColumns; j++) 
      for (unsigned int k = 0; k < lColumns; k++) 
       mulResult[i][k] += lhs[i][k] * rhs[k][j]; 
    return addResult; 
} 
+0

Что такое определение '' оператора *? Пожалуйста, добавьте его в вопрос. В вопросе есть только объявление друга. – Tobias

+0

Компиляция не доходит до определения, поэтому я пропустил ее.Вот он, если он имеет значение шаблон <класс T, без знака int Строки, неподписанные int Столбцы> Matrix2D оператор * (const Matrix2D & lhs, const Matrix2D < T, rRows, rColumns> & rhs) { \t Matrix2D mulResult; \t \t для (беззнаковое INT I = 0; г

+0

@UriRaz: вы можете отредактировать свой вопрос, а не добавлять реализацию в комментарий. – Jarod42

ответ

2

Вы не можете друг специализацию необъявленной функции шаблона. Конечно, объявляя операторы перед определением шаблона класса потребует от вас вперед объявить, а также:

template <class T, unsigned int Rows, unsigned int Columns> 
class Matrix2D; 

template <class T, unsigned int Rows, unsigned int Columns> 
Matrix2D<T, Rows, Columns> 
operator+ (const Matrix2D<T, Rows, Columns> &lhs, const Matrix2D<T, Rows, Columns> &rhs); 

template <class T, unsigned int Rows, unsigned int Columns> 
Matrix2D<T, Rows, Columns> 
operator* (const Matrix2D<T, Rows, Columns> &lhs, const Matrix2D<T, Rows, Columns> &rhs); 

template <class T, unsigned int Rows, unsigned int Columns> 
class Matrix2D 
{ 
private: 
    array<array<T,Columns>, Rows> m_Matrix; 

public: 
    Matrix2D() {} 

    array<T,Columns>& operator[](unsigned int row)  { return m_Matrix[row]; } 
    const array<T,Columns>& operator[](unsigned int row) const { return m_Matrix[row]; } 

    friend Matrix2D operator+ <> (const Matrix2D &lhs, const Matrix2D &rhs); 
    friend Matrix2D operator* <> (const Matrix2D &lhs, const Matrix2D &rhs); 
}; 

в качестве альтернативы, вы можете взять легкий путь и определить отдельные функции оператора для каждой специализации Matrix2D:

template <class T, unsigned int Rows, unsigned int Columns> 
class Matrix2D 
{ 
private: 
    array<array<T,Columns>, Rows> m_Matrix; 

public: 
    Matrix2D() {} 

    array<T,Columns>& operator[](unsigned int row)  { return m_Matrix[row]; } 
    const array<T,Columns>& operator[](unsigned int row) const { return m_Matrix[row]; } 

    friend Matrix2D operator+ (const Matrix2D &lhs, const Matrix2D &rhs) { 
     // do stuff that adds. 
    } 
    friend Matrix2D operator* (const Matrix2D &lhs, const Matrix2D &rhs) { 
     // do stuff that multiplies. 
    } 
}; 

, который я, вероятно, использовал бы для более простого общего синтаксиса.

EDIT: Правильное умножение неквадратных матриц означает, что функция operator* действительно должна была быть знакома с тремя различными специализациями Matrix2D: тип левого операнда, правый операнд и результат. Я думаю, что первый подход здесь станет несостоятельным. Вы должны либо друг все специализации operator*:

template <class T, unsigned int Rows, unsigned int Columns> 
class Matrix2D 
{ 
    // ... 

    template <typename U, typename V, unsigned Rows, unsigned Common, unsigned Columns> 
    friend Matrix2D<decltype(std::declval<U>()+std::declval<V>()), Rows, Columns> 
    operator * (const Matrix2D<U, Rows, Common>&, 
       const Matrix2D<V, Common, Columns>&); 

}; 

или просто сделать общественность данных (вероятно, лучший подход для класса «коллекция-оф-данных» абы).

1

В:

template <class T, unsigned int Rows, unsigned int Columns> 
class Matrix2D 
{ 
    // ... 
    friend Matrix2D operator* <> (const Matrix2D &lhs, const Matrix2D &rhs); 
}; 

Matrix2D см на деле Matrix2D<T, Rows, Columns>.

И ваш operator * должен быть

template <T, unsigned Rows1, unsigned int Common, unsigned int Column> 
Matrix2D<T, Row1, Column> operator* (const Matrix2D<T, Row1, Common>& lhs, const Matrix2D<T, Common, Column>& rhs); 
Смежные вопросы