Матричный оператор * = c ++ возвращает ошибку - PullRequest
1 голос
/ 05 апреля 2011

Доброе утро.Я имел дело с этой ошибкой в ​​течение 3 дней, и я не могу понять это.Мне было поручено создать заголовочный файл для серии матричных тестов, чтобы научиться использовать шаблоны на c ++.Кажется, у меня работают все остальные операторы, кроме оператора * =.Я включаю заголовочный файл, плюс получаю ошибку.

#ifndef MATRIX_H
#define MATRIX_H
#include <vector>
#include <iostream>
#include <math.h>
#include <complex>

using namespace std;
namespace nkumath {

template <typename T, size_t ROWS, size_t COLS>
class Matrix {
    friend class Matrix;
public:

    Matrix(const T & init = T()) : elts(ROWS, vector<T>(COLS, init)) {
    };

    const vector<T> & operator[](int ROWS) const {
        return elts[ROWS];
    }; //not sure if correct

    vector<T> & operator[](int ROWS) {
        return elts[ROWS];
    }; //not sure if correct

    //MatrixAdd
    Matrix & matrixAdd(const Matrix & lhs, const Matrix & rhs) {
        for (int r = 0; r < ROWS; r++) {
            for (int c = 0; c < COLS; c++) {
                this->elts[r][c] = lhs[r][c] + rhs[r][c];
            }
        }
        return *this;
    };

    //MatrixSubtract

    Matrix & matrixSubtract(const Matrix & lhs, const Matrix & rhs) {

        for (int r = 0; r < ROWS; r++) {
            for (int c = 0; c < COLS; c++) {
                this->elts[r][c] = lhs[r][c] - rhs[r][c];
            }
        }
        return *this;
    };

    //MatrixMult

    template<size_t INNER>
    Matrix & matrixMult(const Matrix<T, ROWS, INNER> & mat1, const Matrix<T, INNER, COLS> & mat2) {
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                //elts[i][j] = 0;
                for (int k = 0; k < INNER; k++) {
                    elts[i][j] += mat1.elts[i][k] * mat2.elts[k][j];
                }
            }
        }
        return *this;
    }; //not done

    //print function

    void print(ostream & out) const {
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                out << elts[i][j];
            }
            out << "\n";
        }
    };

private:
    vector< vector<T> > elts;
};
//Note, you have to define each time a template to avoid having the errors
//Operator<<

template <typename T, size_t ROWS, size_t COLS>
ostream & operator<<(ostream & out, const Matrix<T, ROWS, COLS> & elts) {
    elts.print(out);
    return out;
};

//Operator==

template <typename T, size_t ROWS, size_t COLS>
bool operator==(const Matrix<T, ROWS, COLS> & lhs, const Matrix<T, ROWS, COLS> & rhs) {
    return true;
};
//Operator+

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> returnVal;
    return returnVal.matrixAdd(lhs, rhs);
};
//Operator-

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> returnVal;
    return returnVal.matrixSubtract(lhs, rhs);
};
//Operator*

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> returnVal;
    return returnVal.matrixMult(lhs, rhs);
};

//Operator+=

template <typename T, size_t ROWS, size_t COLS, typename C>
Matrix<T, ROWS, COLS> operator+=(Matrix<T, ROWS, COLS> & lhs, const C & rhs) {
    //Matrix<T,ROWS,COLS> returnVal;
    lhs.matrixAdd(lhs, rhs);
    return lhs;
};

//Operator-=

template <typename T, size_t ROWS, size_t COLS, typename C>
Matrix<T, ROWS, COLS> operator-=(Matrix<T, ROWS, COLS> & lhs, const C & rhs) {
    lhs.matrixSubtract(lhs, rhs);
    return lhs;
};
//Operator*=

template <typename T, size_t ROWS, size_t COLS, typename C>
Matrix<T, ROWS, COLS> operator*=(Matrix<T, ROWS, COLS> & lhs, const C & rhs) {
    lhs.matrixMult(lhs, rhs);
    return lhs;
};
//Operator/=

template <typename T, size_t ROWS, size_t COLS>
Matrix<T, ROWS, COLS> operator/=(const Matrix<T, ROWS, COLS> & lhs, const int rhs) {
    Matrix<T, ROWS, COLS> returnVal(rhs);
    for (int r = 0; r < ROWS; r++) {
        for (int c = 0; c < COLS; c++) {
            returnVal[r][c] = lhs[r][c] / returnVal[r][c];
        }
    }
    return returnVal;
};
//Operator%=

template <typename T, size_t ROWS, size_t COLS>
Matrix<T, ROWS, COLS> operator%=(const Matrix<T, ROWS, COLS> & lhs, const int rhs) {
    Matrix<T, ROWS, COLS> returnVal(rhs);
    for (int r = 0; r < ROWS; r++) {
        for (int c = 0; c < COLS; c++) {
            returnVal[r][c] = lhs[r][c] % returnVal[r][c];
        }
    }
    return returnVal;
};
    } // namespace Matrix

    #endif // MATRIX_H

вот мой main.cpp.Мне не разрешено изменять этот файл ....

// main.cpp
// Test driver for Matrix class template project.
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>  // for rand()
#include "Matrix.h"

using namespace std;
using namespace nkumath;

template <typename T, size_t ROWS, size_t COLS>
void randomize(Matrix<T, ROWS, COLS> & mat)
// Put random values in a Matrix.
// Note:  It must be possible to assign T an int value.
{
for (size_t i = 0; i < ROWS; i++)
    for (size_t j = 0; j < COLS; j++)
        mat[i][j] = (rand() % 21) - 10; // Random number in range -10,...,+10
}

struct Complex
{
Complex(double re = 0.0, double im = 0.0) : real(re), imag(im) { }
Complex & operator+=(const Complex & rhs)
{
    real += rhs.real;
    imag += rhs.imag;
    return *this;
}
Complex & operator-=(const Complex & rhs)
{
    real -= rhs.real;
    imag -= rhs.imag;
    return *this;
}
Complex & operator*=(const Complex & rhs)
{
    real = real * rhs.real - imag * rhs.imag;
    imag = real * rhs.imag + imag * rhs.real;
    return *this;
}
double real;
double imag;
};
Complex operator+(const Complex & lhs, const Complex & rhs)
{
return Complex(lhs.real + rhs.real, lhs.imag + rhs.imag);
}
Complex operator-(const Complex & lhs, const Complex & rhs)
{
return Complex(lhs.real - rhs.real, lhs.imag - rhs.imag);
}
Complex operator*(const Complex & lhs, const Complex & rhs)
{
return Complex(lhs.real * rhs.real - lhs.imag * rhs.imag, lhs.real * rhs.imag + lhs.imag * rhs.real);
}
ostream & operator<<(ostream & out, const Complex & c)
{
out << "(" << c.real << " + " << c.imag << "i)";
return out;
}


int main()
{
srand(100);
ofstream out("output.txt");

// Matrix construction, operator[], and printing:
Matrix<int, 4, 5> m1(2);
out << "m1: " << endl;
m1.print(out);
const Matrix<int, 4, 5> m2 = m1;
out << "m2: " << endl << m2;
for (size_t i = 0; i < 4; i++)
    m1[i][i] = 5;
out << "m1: " << endl << m1;

// Tests of const correctness:
// m2[0][0] = 0; // This line should not compile.
// m2 += 4; // Neither should this one.
int n = m2[0][0]; // This line should be okay.

// Scalar operation tests:
out << "m1 += 4: "  << endl << (m1 += 4);
out << "m1 -= 6: " << endl << (m1 -= 6);
out << "m1 *= 12: " << endl << (m1 *= 12);
out << "m1 /= 2: " << endl << (m1 /= 2);
out << "m1 %= 7: " << endl << (m1 %= 7);

// Matrix addition and subtraction tests:
Matrix<int, 4, 5> m3;
out << "m3: " << endl << m3;
out << "m3.matrixAdd(m1, m2): " << endl << m3.matrixAdd(m1, m2);
out << "m3.matrixSubtract(m1, m2): " << endl << m3.matrixSubtract(m1, m2);
out << "m2 + m1: " << endl << (m2 + m1);
out << "m2 - m1: " << endl << (m2 - m1);

// Matrix multiplication tests:
Matrix<int, 2, 3> m4;
randomize(m4);
out << "m4: " << endl << m4;
Matrix<int, 3, 5> m5;
randomize(m5);
out << "m5: " << endl << m5;
Matrix<int, 2, 5> m6;
out << "m6.matrixMult(m4, m5): " << endl << m6.matrixMult(m4, m5);
Matrix<int, 2, 5> m7;
matrixMult(m4, m5, m7);
out << "m6 == m7: " << (m6 == m7) << endl;
out << "m6 == m4 * m5: " << (m6 == m4 * m5) << endl;

// Matrices of strings:
Matrix<string, 3, 4> m8("Hello");
for (size_t i = 0; i < 3; i++)
    m8[i][i] = "   Hi";
out << "m8: " << endl << m8 << endl;
Matrix<string, 3, 4> m9(" there!");
out << "m9: " << endl << m9 << endl;
out << "m8 + m9: " << endl << m8 + m9 << endl;
Matrix<string, 4, 5> m10(", Goodbye!");
//out << m8 * m10 << endl; // This line should not compile.

// Matrices of Complex:
Matrix<Complex, 2, 8> m11;
randomize(m11);
Complex c(1, -3);
m11 += c;
out << "m11: " << endl << m11 << endl;
Matrix<Complex, 8, 3> m12;
randomize(m12);
m12 -= c;
out << "m12: " << endl << m12 << endl;
out << "m11 * m12: " << endl << m11 * m12 << endl;

out.close();
}

Я получаю ошибку

Error   1   error C2784: 'nkumath::Matrix<T,ROWS,COLS> &nkumath::Matrix<T,ROWS,COLS>::matrixMult(const nkumath::Matrix<T,4,INNER> &,const nkumath::Matrix<T,INNER,5> &)' : could not deduce template argument for 'const nkumath::Matrix<T,INNER,5> &' from 'const int' e:\documents and settings\pato\my documents\visual studio 2010\projects\thematrix\thematrix\matrix.h    136

Я использую Visual Studio C ++ 2010. Я попытался скомпилировать заголовокна Linux GCC4 и я получаю совершенно другой набор ошибок, поэтому я собираюсь закончить этот проект в Windows.В любом случае, просто нужно, чтобы кто-то указывал мне правильное направление, я смотрел на это слишком долго.Спасибо!PJ

Ответы [ 2 ]

2 голосов
/ 05 апреля 2011

У меня есть код, скомпилированный в codepad.org здесь

Остался ли вопрос?

1 голос
/ 05 апреля 2011

В вашей главной

  1. вы пропустили объявления using namespace std и using namespace nkumath
  2. есть вызов matrixMult(m4, m5, m7);, который не может быть разрешен. Я предполагаю, что вы имеете в виду m7 = m4*m5;

Похоже, вы неправильно превратили ранее статический matrixMult (со значением innerproduct) в функцию-член Matrix;

Использование этого как автономной статической функции работает:

    template<class T, size_t ROWS, size_t INNER, size_t COLS>
    static Matrix<T, ROWS, COLS> innerProduct(const Matrix<T, ROWS, INNER> & mat1, const Matrix<T, INNER, COLS> & mat2) {
        Matrix<T, ROWS, COLS> result;
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                //elts[i][j] = 0;
                for (int k = 0; k < INNER; k++) {
                    result.elts[i][j] += mat1.elts[i][k] * mat2.elts[k][j];
                }
            }
        }
        return result;
    } //not done

Обновление

Это означает, что вы должны переписать метод matrixMult следующим образом (с помощью вышеуказанного статического помощника innerProduct):

    template<size_t OUTER>
    Matrix<T, ROWS, OUTER> matrixMult(const Matrix<T, COLS, OUTER> & mat2) const {
        return innerProduct(*this , mat2);
    }

добавление чего-то вроде этого, вероятно, то, что вы хотите:

template<class T, size_t ROWS, size_t INNER, size_t COLS>
Matrix<T, ROWS, COLS> operator*(const Matrix<T, ROWS, INNER> & lhs, const Matrix<T, INNER, COLS> & rhs)
    {
        return innerProduct(lhs, rhs);
    }

Я не удосужился исправить скалярное умножение, но вы должны понять это сейчас (если я не трачу свое время). Удачи

Таким образом, main.cpp может остаться таким, каким он был ... capice?


Это мое итоговое определение класса Matrix для вашего прочтения:

namespace nkumath {

    template <typename T, size_t ROWS, size_t COLS>
    class Matrix {
    public:

        Matrix(const T & init = T()) : elts(ROWS, vector<T>(COLS, init)) {
        }

        const vector<T> & operator[](int r) const {
            return elts[r];
        } //not sure if correct

        vector<T> & operator[](int r) {
            return elts[r];
        } //not sure if correct

        //MatrixAdd
        Matrix & matrixAdd(const Matrix & lhs, const Matrix & rhs) {
            for (int r = 0; r < ROWS; r++) {
                for (int c = 0; c < COLS; c++) {
                    this->elts[r][c] = lhs[r][c] + rhs[r][c];
                }
            }
            return *this;
        }

        //MatrixSubtract

        Matrix & matrixSubtract(const Matrix & lhs, const Matrix & rhs) {

            for (int r = 0; r < ROWS; r++) {
                for (int c = 0; c < COLS; c++) {
                    this->elts[r][c] = lhs[r][c] - rhs[r][c];
                }
            }
            return *this;
        }

        //MatrixMult

        template<size_t OUTER>
        Matrix<T, ROWS, OUTER> matrixMult(const Matrix<T, COLS, OUTER> & mat2) const {
            return innerProduct(*this , mat2);
        } //not done

        //print function

        void print(ostream & out) const {
            for (int i = 0; i < ROWS; i++) {
                for (int j = 0; j < COLS; j++) {
                    out << elts[i][j];
                }
                out << "\n";
            }
        }

    private:
        vector< vector<T> > elts;
    };
    //Note, you have to define each time a template to avoid having the errors
    //Operator<<

        template<class T, size_t ROWS, size_t INNER, size_t COLS>
        static Matrix<T, ROWS, COLS> innerProduct(const Matrix<T, ROWS, INNER> & mat1, const Matrix<T, INNER, COLS> & mat2) {
            Matrix<T, ROWS, COLS> result;
            for (int i = 0; i < ROWS; i++) {
                for (int j = 0; j < COLS; j++) {
                    //elts[i][j] = 0;
                    for (int k = 0; k < INNER; k++) {
                        result.elts[i][j] += mat1.elts[i][k] * mat2.elts[k][j];
                    }
                }
            }
            return result;
        } //not done
    template <typename T, size_t ROWS, size_t COLS>
    ostream & operator<<(ostream & out, const Matrix<T, ROWS, COLS> & elts) {
        elts.print(out);
        return out;
    }

    //Operator==

    template <typename T, size_t ROWS, size_t COLS>
    bool operator==(const Matrix<T, ROWS, COLS> & lhs, const Matrix<T, ROWS, COLS> & rhs) {
        return true;
    }
    //Operator+

    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> returnVal;
        return returnVal.matrixAdd(lhs, rhs);
    }
    //Operator-

    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> returnVal;
        return returnVal.matrixSubtract(lhs, rhs);
    }
    //Operator*

    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> returnVal;
        return returnVal.matrixMult(lhs, rhs);
    }

    //Operator+=

    template <typename T, size_t ROWS, size_t COLS, typename C>
    Matrix<T, ROWS, COLS> operator+=(Matrix<T, ROWS, COLS> & lhs, const C & rhs) {
        //Matrix<T,ROWS,COLS> returnVal;
        lhs.matrixAdd(lhs, rhs);
        return lhs;
    }

    //Operator-=

    template <typename T, size_t ROWS, size_t COLS, typename C>
    Matrix<T, ROWS, COLS> operator-=(Matrix<T, ROWS, COLS> & lhs, const C & rhs) {
        lhs.matrixSubtract(lhs, rhs);
        return lhs;
    }
    //Operator*=

    template <typename T, size_t ROWS, size_t COLS, typename C>
    Matrix<T, ROWS, COLS> operator*=(Matrix<T, ROWS, COLS> & lhs, const C & rhs) {
        lhs.matrixMult(lhs, rhs);
        return lhs;
    }
    //Operator/=

    template <typename T, size_t ROWS, size_t COLS>
    Matrix<T, ROWS, COLS> operator/=(const Matrix<T, ROWS, COLS> & lhs, const int rhs) {
        Matrix<T, ROWS, COLS> returnVal(rhs);
        for (int r = 0; r < ROWS; r++) {
            for (int c = 0; c < COLS; c++) {
                returnVal[r][c] = lhs[r][c] / returnVal[r][c];
            }
        }
        return returnVal;
    }
    //Operator%=

    template <typename T, size_t ROWS, size_t COLS>
    Matrix<T, ROWS, COLS> operator%=(const Matrix<T, ROWS, COLS> & lhs, const int rhs) {
        Matrix<T, ROWS, COLS> returnVal(rhs);
        for (int r = 0; r < ROWS; r++) {
            for (int c = 0; c < COLS; c++) {
                returnVal[r][c] = lhs[r][c] % returnVal[r][c];
            }
        }
        return returnVal;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...