Перегрузка операторов с экземпляром класса в правой части

Я пытаюсь выполнить перегрузку оператора * в своем классе Matrix.

У меня есть один, который делает это, если это Matrix*что-то, (int, double...)

я ищу тот, который делает это для противоположной стороны, т.е. что-то * Матрица

это то, что я пытался

template<class T>
bool operator*(Matrix<T>& other ){
Matrix<T> mat(other.rows,other.columns);
for(int i=0;i<other.rows;i++){
    for(int j=0;j<other.columns;j++){
        T temp=other.get(i,j);
        temp=temp*(this);
        mat.set(i,j,temp);
    }
}
return mat;
}    

и это то, что работает для Matrix*что-то

 Matrix<T>& operator*(const T & num){
    Matrix<T> mat(rows,columns);
    for(int i=0;i<rows;i++){
        for(int j=0;j<columns;j++){
            T temp=(matrix[i][j]);
            temp=temp*num;
            mat.set(i,j,temp);
        }
    }
    return mat;
}    

person keiloda    schedule 13.01.2015    source источник


Ответы (1)


Вы должны сделать его не членом, то есть вы пишете вне класса Matrix:

template<class T>
Matrix<T> operator*(const T& num, const Matrix<T>& mat) {
    return mat * num; // invoke existing implementation of Matrix * something
}

Обратите внимание, что operator* должен возвращать результат по значению. В вашей реализации есть ошибка, вы возвращаете оборванную ссылку на локальную переменную mat.

Обратите внимание, что эта форма требует, чтобы num имел тип T, поэтому, если, как в вашем примере, у вас есть

Matrix<Rational> mat;
mat = 3 * mat;

он не скомпилируется, потому что 3 не Rational.

Что вы можете сделать, так это использовать идентификационный трюк, чтобы поместить параметр num в невыведенный контекст, поэтому он будет преобразован из int в Rational:

template<class T>
Matrix<T> operator*(typename boost::mpl::identity<T>::type const& num, const Matrix<T>& mat) {
    return mat * num; // invoke existing implementation of Matrix * something
}

Где identity просто

template<typename T> 
struct identity { typedef T type; };

Или вы можете сделать просто

template<class T, class U>
Matrix<T> operator*(const U& num, const Matrix<T>& mat) {
    return mat * num; // invoke existing implementation of Matrix * something
}
person Anton Savin    schedule 13.01.2015
comment
я попробовал это, и я получил некоторую ошибку компиляции main.cpp: 71: 5: ошибка: нет совпадения для «оператора *» (типы операндов — «int» и «Matrix‹Rational›») m = 3 * m; ^ main.cpp:71:5: примечание: кандидат: В файле, включенном из main.cpp:3:0: Matrix.hpp:229:12: примечание: шаблон‹класс T›Матрица‹T›& оператор*(const T&, const Matrix‹T›&) Matrix‹T›& operator*(const T& num,const Matrix‹T› &matr){ ^ Matrix.hpp:229:12: примечание: вывод/подстановка аргумента шаблона не удалась: main.cpp :71:6: примечание: выведены конфликтующие типы для параметра 'T' ('int' и 'Rational') m=3*m; ^ - person keiloda; 15.01.2015
comment
@keiloda Это говорит само за себя - 3 равно int, а не Rational, поэтому несоответствие типов. - person Anton Savin; 15.01.2015