2016-09-15 11 views
0

カスタム行列クラスで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:

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(のようなメソッドを呼び出す):これは、操作者の問題であるかどうかを試験するために、私は(MatrixBaseで)次のメソッドを作成します。これは期待どおりに動作します。

残念ながら、プログラムはラインOS < <行列(I、0)で停止したとして、デバッガが有用な情報を与えていない、と私はプログラムが情報を取得するために停止したとき、それは、フレーム(Clionの取得に失敗したと言いますデバッガ)

+0

テンプレートが長く畳み込まれ、一般に読んで理解しにくい傾向があるが、完全なエラー出力を(テキストとして、完全に、編集なしで)コピー&ペーストすることができれば、あなたの質問の本文。それをコードとしてフォーマットします。 –

+0

エラーコードはまったくありません。プログラムはコンパイルして実行しますが、決して何も出力せず決して終了しません –

+1

デバッグモードでコードをステップバイステップで実行して呼び出しスタックを表示しますが、 'operator()'呼び出しが無限再帰につながるように見えます – wasthishelpful

答えて

1

(メンバ関数MatrixBaseoperator()は無条件に自分自身を呼び出すため、無限に再帰的です。

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を使用してください。さらに、標準のコンテナを使用してください。

+0

A !!!!!これは非常にばかげた質問です!今私は問題を見る!ありがとう! –

関連する問題