Матричный оператор класса C ++, использующий std :: common_type_t и реализацию комплексного числа - PullRequest
0 голосов
/ 09 октября 2018

Я пишу матричный класс сам и пытаюсь сделать его как можно более «универсальным», т. Е. Я хочу, чтобы matrix<int> + matrix<double> мог дать matrix<double>, matrix<double> * matrix<int>, способный дать matrix<double>.

Итак, в моем operator+ мое объявление в классе:

template<typename T>
class Matrix {
public:
    ......
    template <typename TT> Matrix operator+(const Matrix<TT>&);
    ......
private:
    ......
}

, а определение -

template<typename T, typename TT>
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;
}

Однако компилятор жалуется, что

список аргументов шаблона должен соответствовать списку параметров

Я не знаю, где что-то не так.Может кто-нибудь помочь мне здесь?Спасибо.

Что касается реализации комплексного числа.Есть некоторые операции, которые несовместимы с std :: complex, такие как max, min, operator <и т. Д. Решение, которое я придумал, я написал новый класс матрицы для комплексной матрицы, но это глупо.Есть ли простой способ обойти это? </p>

==================================================================================

Мой конструктор:

template <typename T>
Matrix<T>::Matrix() { allocate(0.0); }    // this is a private function allocating memory

член allocate

template<typename T>
void Matrix<T>::allocate(T val)
{
    mtx = new T [_rows * _cols];
    if(val) {
        for (size_t i = 0; i < _rows * _cols; ++i)
            mtx[i] = val;
    }
}

1 Ответ

0 голосов
/ 09 октября 2018

Вы не должны смешивать два шаблона в один.Попробуйте это:

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.Я не знаю, как обойти это, если я использую сложную матрицу.

Хорошо иметь этот член в классе шаблона.Только не используйте его со сложными матрицами.Тем не менее, я предлагаю вам сделать его бесплатной функцией .Тогда у тебя не будет этой заботы вообще.

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