繁体   English   中英

如何解决这些错误? “'template std :: ostream&operator <<的重新定义”,“未解析的重载函数类型”

[英]How can I fix these errors? “redefinition of 'template std::ostream& operator<<” , “unresolved overloaded function type”

给出以下代码:

#ifndef MATRIX_H_
#define MATRIX_H_

#include <iostream>
#include <vector>

using std::ostream;
using std::vector;
using std::string;


class BadDims: public std::exception {
public:
    const char* what() const throw () override {
        return "Bad dimensions";
    }
};

template<class T>
class Row {
    std::vector<T> row;
public:
    Row() = default;
    Row(int cols) :
            row(cols, T()) {
    }
    ~Row() = default;
    Row& operator=(const Row& r) = default;
    const T& operator[](unsigned int i) const {
        if (i < 0 || i >= row.size()) {
            throw std::exception();
        }
        return this->row[i];
    }

    T& operator[](unsigned int i) {
        if (i < 0 || i >= row.size()) {
            throw std::exception();
        }
        return this->row[i];
    }
};

template<class T>
T Plus(const T& t1, const T& t2) {
    return t1 + t2;
}

template<class T>
class Matrix {
    Row<T>* rows;
    int numberOfRows; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error1
    int numberOfCols; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error2

public:
    Matrix(int numberOfRows, int numberOfCols) :
            rows(new Row<T> [numberOfRows]), numberOfRows(
                    numberOfRows), numberOfCols(numberOfCols) {
        for (int i = 0; i < numberOfRows; i++) {
            this->rows[i] = Row<T>(numberOfCols);
        }
    }

    ~Matrix() {
        delete[] rows;
    }

    Matrix(const Matrix& m) :
            rows(new Row<T> [m.numberOfRows]), numberOfRows(m.numberOfRows), numberOfCols(m.numberOfCols) {
        for (int i = 0; i < m.numberOfRows; i++) {
            this->rows[i] = m.rows[i];
        }
    }

    Matrix& operator=(const Matrix<T>& m) {
        if (this == &m) {
            return *this;
        }
        if (this->numberOfCols != m.numberOfCols
                || this->numberOfRows != m.numberOfRows) {
            throw BadDims();
        }
        Row<T>* newRows = new Row<T> [m.numberOfRows];
        for (int i = 0; i < m.numberOfRows; i++) {
            newRows[i] = m.rows[i];
        }
        delete[] this->rows;
        this->rows = newRows;
        return *this;
    }

    const Row<T>& operator[](int i) const {
        if (i < 0 || i >= this->numberOfRows) {
            throw std::exception();
        }
        return this->rows[i];
    }

    Row<T>& operator[](int i) {
        if (i < 0 || i >= this->numberOfRows) {
            throw std::exception();
        }
        return this->rows[i];
    }

    void getDimensions(int* outN, int* outM) const {
        if (outN == NULL || outM == NULL) {
            throw std::exception();
        }
        *outN = numberOfRows;
        *outM = numberOfCols;
    }

    template<class S>
    friend ostream& operator<<(ostream& os, const Matrix<S>& m) { // ~~~~~~~~~~~~~~~~ error3
        for (int i = 0; i < m.numberOfRows; i++) {
            for (int j = 0; j < m.numberOfCols; j++) {
                os << m[i][j] << " ";
            }
            os << std::endl;
        }
        return os;
    }

    Matrix& operator+=(const Matrix<T>& m) {
        if (this->numberOfCols != m.numberOfCols
                || this->numberOfRows != m.numberOfRows) {
            throw BadDims();
        }
        *this = *(matAction(this, &m, Plus)); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error4
        return *this;
    }
};

template<class T, class Action>
Matrix<T>* matAction(const Matrix<T>* m1, const Matrix<T>* m2, Action action) {
    if (m1 == NULL || m2 == NULL) {
        return NULL;
    }
    int rows1 = 0, cols1 = 0;
    m1->getDimensions(&rows1, &cols1);
    int rows2 = 0, cols2 = 0;
    m2->getDimensions(&rows2, &cols2);
    if (rows1 != rows2 || cols1 != cols2) {
        throw std::exception();
    }
    Matrix<T>* res = new Matrix<T>(rows1, cols1);
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols1; j++) {
            (*res)[i][j] = action((*m1)[i][j], (*m2)[i][j]);
        }
    }
    return res;
}

template<class T>
Matrix<T> operator+(const Matrix<T>& m1, const Matrix<T>& m2) {
    return Matrix<T>(m1) += m2;
}

/*
 * Implementation of Vector by Matrix.
 */
template<class T>
class Vector: public Matrix<T> {
public:
    Vector(int cols) :
            Matrix<T>(1, cols) {
    }

    const T operator[](int col) const {
        return Matrix<T>::operator[](0).operator[](col);
    }

    T& operator[](int col) {
        return Matrix<T>::operator[](0).operator[](col);
    }
};

/*
 * SquareMatrix from size SIZE x SIZE.
 */
template<class T, int SIZE>
class SquareMatrix: public Matrix<T> {
public:
    SquareMatrix() :
            Matrix<T>(SIZE, SIZE) {
    }
    template<class S, int N>
    friend ostream& operator<<(ostream& os, const SquareMatrix<S, N>& m) {
        for (int i = 0; i < m.numberOfRows; i++) {
            for (int j = 0; j < m.numberOfCols; j++) {
                os << m[i][j] << " ";
            }
            os << std::endl;
        }
        return os;
    }
};

#endif /* MATRIX_H_ */

我收到以下错误(四个错误,您可以通过ctrl+f并通过搜索单词error来找到它们):

'int Matrix :: numberOfRows'是私有的

'int Matrix :: numberOfCols'是私有的

重新定义'template std :: ostream&operator <<(std :: ostream&,const Matrix&)'

没有匹配的函数来调用'matAction(Matrix ,const Matrix ,<无法解析的重载函数类型>)'

我在一个问题中要求所有这些错误,因为所有这些错误都与此代码相关,而且我不明白为什么我也不能为SquareMatrix定义operator<< ,尤其是当我尝试从SquareMatrix的operator<<访问在Matrix定义的字段,我不明白,因为SquareMatrix operator<<被定义为friend ,因此,需要从的类型访问object的字段SquareMatrix那么该错误的原因是什么?

另外,什么是unresolved overloaded function type 在这种情况下如何解决?

Matrix<U>每个实例化都会对template<class S> ostream& operator<<(ostream& os, const Matrix<S>& m)的新定义添加标记-这就是为什么您会得到重新定义错误的原因。

正确的舞蹈是这样-声明Matrix模板,声明operator<< ,然后定义Matrix并声明operator<<作为那里的朋友,最后,定义operator<< 像这样:

template<class T> class Matrix;

template<class S>
ostream& operator<<(ostream& os, const Matrix<S>& m);

template<class T>
class Matrix {
  // ...
  template<class S>
  friend ostream& operator<<(ostream& os, const Matrix<S>& m);
};

template<class S>
ostream& operator<<(ostream& os, const Matrix<S>& m) {
  // ...
  return os;
}

定义一个常规的公共方法通常会更容易一些,比如说执行实际工作的void print(ostream& os) ,然后实现operator<<就像调用它一样简单。 这样,您就不必为模板模板搞混了,要正确使用它有些棘手。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM