사용자 정의 매트릭스 클래스로 CRTP를 사용하려고합니다. 이제 ostream 연산자에 오버로드를 시도하고 있습니다. https://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx을 따르십시오.사용자 정의 클래스의 ostream 연산자 오버로드
그러나 모든 것이 컴파일 중이지만 프로그램이 존재하지 않고 화면에 아무 것도 인쇄하지 않습니다. 나는 무슨 일이 일어나고 있는지 내 머리를 긁적이다.
여하튼,이 관련 코드가 전체 프로그램을 사용하여 컴파일된다
#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)
EDIT : 이 오퍼레이터의 문제인지 여부를 테스트하기 위해, I는 (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과 같은 방법()를 호출한다. 이것은 예상대로 작동합니다.
불행하게도 디버거는 프로그램이 줄 < < 행렬 (i, 0)에서 멈 춥니 다. 정보를 검색하기 위해 프로그램을 멈추었을 때 프레임을 가져 오지 못했습니다 (Clion as 디버거)
템플릿이 길고 복잡하고 읽기 쉽고 일반적으로 이해하기 쉬운 경향이있는 오류가 있지만 전체 오류 출력을 전체 텍스트와 편집없이 텍스트로 복사하여 붙여 넣을 수 있다면 매우 유용합니다. 귀하의 질문의 본문. 그것을 코드로 포맷하십시오. –
오류 코드가 전혀 없습니다. 프로그램을 컴파일하고 실행하지만 아무 것도 출력하지 않고 절대 종료하지 마십시오 –
디버그 모드에서 코드를 단계별로 실행하여 호출 스택을 확인하지만 'operator()'호출이 무한 재귀 호출로 이어지는 것 같습니다 – wasthishelpful