![](/img/trans.png)
[英]can i pass std::ostream& to a function expecting std::ofstream
[英]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.