我正在尝试使用带有自定义矩阵类的CRTP。现在,我正在尝试重载ostream运算符,请遵循https://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx。但是,所有内容似乎都在编译,但是该程序从不存在,并且在屏幕上不打印任何内容。我正在挠头,正在发生的事情。无论如何,这是相关的代码(抱歉,这有点冗长)#ifndef EXPERIMENT_POINTERMATRIX_H#define EXPERIMENT_POINTERMATRIX_H#include <cstdlib>#include <ostream>#include "macro.h"namespace PM { template<typename T, typename Derived> class MatrixBase{ public: size_t nRow; size_t nCol; MatrixBase(const size_t nRow_,const size_t nCol_):nRow(nRow_), nCol(nCol_){} Derived& derived(){ return *static_cast<Derived*>(this); } const Derived& derived() const{ return *static_cast<Derived*>(this); } T& operator()(const size_t i, const size_t j){ CHECK_BOUND(i,j,*this); return derived().operator()(i,j); } const T& operator()(const size_t i, const size_t j) const { return const_cast<T&>( static_cast<const MatrixBase<T, Derived>&>(*this).operator()(i,j)); } inline T rows(){ return nRow; } const T rows() const { return nRow; } inline T cols(){ return nCol; } const T cols() const { return nCol; } template<typename t1, typename t2> friend std::ostream& operator<<(std::ostream& os, const MatrixBase<t1, t2> & matrix); }; template<typename t1, typename t2> std::ostream& operator<<(std::ostream& os, const MatrixBase<t1, t2>& matrix){ for (size_t i =0;i<matrix.rows();i++){ os << matrix(i,0); if (matrix.cols()>1) { for (size_t j = 1; j < matrix.cols(); j++) { os << "," << matrix(i, j); } } os << std::endl; } return os; }; template<typename T, typename Derived> class Matrix : public MatrixBase<T, Matrix<T, Derived>>{ public: T * data; Matrix(const size_t nRow, const size_t nCol):MatrixBase<T, Matrix<T, Derived>>(nRow, nCol){ data = (T*) malloc(sizeof(T)*nRow*nCol); } ~Matrix(){ free(data); } Derived& derived(){ return *static_cast<Derived*>(this); } const Derived& derived() const{ return *static_cast<Derived*>(this); } T& operator()(const size_t i, const size_t j){ return derived().operator()(i,j); } }; template<typename T, typename Derived> class MatrixView : public MatrixBase<T, MatrixView<T, Derived>>{ public: T * data; MatrixView(const size_t nRow, size_t nCol, T * other):MatrixBase<T, MatrixView<T, Derived>>(nRow, nCol), data(other){} T& operator()(const size_t i, const size_t j){ return derived().operator()(i,j); } Derived& derived(){ return *static_cast<Derived*>(this); } const Derived& derived() const{ return *static_cast<Derived*>(this); } }; template<typename T> class MatrixRowMajor: public Matrix<T, MatrixRowMajor<T>>{ public: MatrixRowMajor(const size_t nRow, const size_t nCol):Matrix<T, MatrixRowMajor<T>>(nRow, nCol){} T& operator()(const size_t i, const size_t j){ using base = MatrixBase<T, Matrix<T, MatrixRowMajor<T>>>; using super = Matrix<T, MatrixRowMajor<T>>; return super::data[i*base::nCol+j]; } }; template<typename T> class MatrixColMajor: public Matrix<T, MatrixColMajor<T>>{ public: MatrixColMajor(const size_t nRow, const size_t nCol):Matrix<T, MatrixColMajor<T>>(nRow, nCol){} T& operator()(const size_t i, const size_t j){ using base = MatrixBase<T, Matrix<T, MatrixColMajor<T>>>; using super = Matrix<T, MatrixColMajor<T>>; return super::data[i+j*base::nRow]; } }; template<typename T> class MatrixViewRowMajor : public MatrixView<T, MatrixViewRowMajor<T>>{ public: MatrixViewRowMajor(const size_t nRow, const size_t nCol, T* other):MatrixView<T, MatrixViewRowMajor<T>>(nRow, nCol, other){} T& operator()(const size_t i, const size_t j){ using base = MatrixBase<T, Matrix<T, MatrixViewRowMajor<T>>>; using super = MatrixView<T, MatrixViewRowMajor<T>>; return super::data[i*base::nCol+j]; } }; template<typename T> class MatrixViewColMajor : public MatrixView<T, MatrixViewColMajor<T>>{ public: MatrixViewColMajor(const size_t nRow, const size_t nCol, T* other):MatrixView<T, MatrixViewRowMajor<T>>(nRow, nCol, other){} T& operator()(const size_t i, const size_t j){ using base = MatrixBase<T, Matrix<T, MatrixViewRowMajor<T>>>; using super = MatrixView<T, MatrixViewRowMajor<T>>; return super::data[i+j*base::nRow]; }};}void test_print(){ using namespace PM; using namespace std; MatrixRowMajor<double> matrix(10, 1); for (int i =0;i<matrix.rows();i++){ matrix(i,0)=1.0; std::cout << "i'th entry is " <<matrix(i,0) << std::endl; //This is fine } std::cout << matrix; //This is not fine}#endif //EXPERIMENT_POINTERMATRIX_H整个程序使用g ++ 4.9编译(启用c ++ 11)编辑:为了测试是否是操作员的问题,我创建了以下方法(在MatrixBase上):void print(){ for (size_t i =0;i<this->rows();i++){ std::cout << this->operator()(i,0); if (this->cols()>1) { for (size_t j = 1; j < this->cols(); j++) { std::cout << "," << this->operator()(i, j); } } std::cout << std::endl; } }并调用诸如matrix.print()之类的方法。这按预期工作。不幸的是,调试器没有提供有用的信息,因为该程序在os 最佳答案 (MatrixBase的成员函数)operator()无条件地调用自身,因此是无限递归的。const T& operator()(const size_t i, const size_t j) const { return const_cast<T&>( static_cast<const MatrixBase<T, Derived>&>(*this).operator()(i,j)); }该函数是尾递归的,因此可以导致无限循环,而不是由于较大的调用深度而崩溃。与您的问题无关,通常不建议在C ++中使用malloc()-特别是在处理可能与C不直接兼容的类型(例如C ++类)时-对于类的用户,取决于类型T,可以不确定。请改用运算符new。更好的是,使用标准容器。关于c++ - 在自定义类中重载ostream运算符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39512409/