Вы не должны смешивать два шаблона в один.Попробуйте это:
template<typename TT>
template<typename T>
Matrix<T> Matrix<TT>::operator+(const Matrix<T> &M)
{
using C = std::common_type_t<T, TT>;
Matrix<C> temp(_rows, _cols);
for (size_t i = 0; i < size(); ++i)
temp.mtx[i] = mtx[i] + M.mtx[i];
return temp;
}
Однако тип возвращаемого значения - Matrix<T>
, а вы возвращаете Matrix<C>
.Поэтому я предлагаю вам написать это так (не забудьте соответствующим образом изменить объявление):
template<typename TT>
template<typename T, typename C = std::common_type_t<T, TT>> // pseudocode, see below
Matrix<C> Matrix<TT>::operator+(const Matrix<T> &M) const
{
Matrix<C> temp(...);
...
return temp;
}
Полный пример:
template<class T>
struct Matrix
{
template<class S, class C = std::common_type_t<T, S>>
Matrix<C> operator+(const Matrix<S>&) const;
};
template<class T>
template<class S, class C>
Matrix<C> Matrix<T>::operator+(const Matrix<S>&) const
{ ... }
Начиная с C ++ 14 вы можете использовать auto
тип возвращаемого значения:
template<class T>
struct Matrix
{
template<class S>
auto operator+(const Matrix<S>&) const
{
using C = std::common_type_t<T, S>;
Matrix<C> tmp(...);
...
return tmp;
}
};
Что касается вашего второго вопроса, неясно, в чем проблема.Обратите внимание, что функции-члены шаблона не создаются, если они не используются.Таким образом, вы можете иметь функции-члены, которые используют, например, operator<
, просто не используйте их со сложными матрицами.
Оператор> здесь несовместим с std :: complex.Я не знаю, как обойти это, если я использую сложную матрицу.
Хорошо иметь этот член в классе шаблона.Только не используйте его со сложными матрицами.Тем не менее, я предлагаю вам сделать его бесплатной функцией .Тогда у тебя не будет этой заботы вообще.