2016-04-05 9 views
2

テンプレートを使用して行列転置のコードを書き込もうとすると、次のエラーが発生します。行列転置テンプレート

エラー1つのエラーC2248:「マトリックス::要素」:プライベートメンバにアクセスすることはできませんクラスで宣言された「マトリックス」

を誰もがこのエラーを修正する方法を私を与えることはできますか?

//Matrix.h 
#include <iostream> 
#include <vector> 
using namespace std; 

template<class T, int m, int n> 
class Matrix; 


template<class T, int m, int n> 
class Matrix 
{ 
vector<vector<T>> elements; 
int nrow; 
int ncol; 

public: 
Matrix(); 
~Matrix(); 
void print(); 

Matrix<T, n, m> transpose(); 

}; 

template<class T, int m, int n> 
Matrix<T, m, n>::Matrix() : nrow(m), ncol(n) 
{ 
for (int i = 0; i < nrow; i++){ 
    vector<T> row(ncol, i); 
    elements.push_back(row); 
} 
} 

template<class T, int m, int n> 
Matrix<T, m, n>::~Matrix(){} 

template<class T, int m, int n> 
Matrix<T, n, m> Matrix<T, m, n>::transpose(){ 
Matrix<T, n, m> m; 
for (int i = 0; i < nrow; ++i){ 
    for (int j = 0; j < ncol; ++j){ 
     m.elements[j][i] = elements[i][j]; 
    } 
} 
return m; 
} 

template<class T, int m, int n> 
void Matrix<T, m, n>::print() 
{ 
for (int i = 0; i < nrow; i++){ 
    for (int j = 0; j < ncol; j++) 
    { 
     cout << elements[i][j] << " "; 
    } 
    cout << endl; 
} 
} 

//main.cpp 

#include "Matrix.h" 
using namespace std; 

int main() 
{ 
Matrix<int, 3, 2> a; 
Matrix<int, 3, 2> b; 
Matrix<int, 2, 3> c; 
c = a.transpose(); 
c.print(); 
} 
+1

テンプレートパラメータと変数の両方に 'm'を使用しています。それらを違うものにする。 –

+0

ありがとう! – SungwonAhn

答えて

1

Matrix<T, n, m>およびMatrix<T, m, n>は、m != nの場合、まったく異なるクラスです。つまり、メンバー関数Matrix<T, m, n>のプライベートメンバーMatrix<T, n, m>にアクセスできなかったことを意味します。あなたが問題を解決するために友人の宣言を追加することができます

template<class T, int m, int n> 
class Matrix 
{ 

    vector<vector<T>> elements; 
    int nrow; 
    int ncol; 

    public: 
    Matrix(); 
    ~Matrix(); 
    void print(); 

    Matrix<T, n, m> transpose(); 

    friend class Matrix<T, n, m>; 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
}; 
+0

コメントありがとうございます! – SungwonAhn

1

問題がmnが一致しない場合Matrix<T, m, n>Matrix<T, n, m>が異なるクラスであるということです。 1人は他のメンバーのprivateにアクセスできません。 メンバ変数へのアクセスを提供するpublicメンバ関数を提供することにより、アクセスの問題を回避できます。

mnが同じ場合は、問題に気付かれません。

+0

ありがとう! – SungwonAhn

0

エラーは、コードに次の関数である:

template<class T, int m, int n> 
Matrix<T, n, m> Matrix<T, m, n>::transpose() { 
    Matrix<T, n, m> m; 
    for (int i = 0; i < nrow; ++i) { 
     for (int j = 0; j < ncol; ++j) { 
      m.elements[j][i] = elements[i][j]; 
     } 
    } 
    return m; 
} 

エラーの理由は、あなたが作成しているということです新しいマトリックスm。この行列要素では、要素はプライベート変数なのでアクセスできません。私は、要素へのポインタを返すためのパブリックゲッター関数を作成するか、要素をパブリック変数にすることを提案します(しかし、データをカプセル化しないので、スタイルは良くないかもしれません)。これはあなたの問題を解決します

template<class T, int m, int n> 
Matrix<T, n, m> Matrix<T, m, n>::transpose() { 
    Matrix<T, n, m> m; 
    for (int i = 0; i < nrow; ++i) { 
     for (int j = 0; j < ncol; ++j) { 
      m.get_elements_ptr()->at(j)[i] = elements[i][j]; 
     } 
    } 
    return m; 
} 

vector<vector<T> >* get_elements_ptr() { 
    return &elements; 
} 

あなたの問題の関数は、その後のようになります。

あなたのgetter関数をシンプルにすることができます。しかし、サイドノートでは、プロジェクトデザインをちょっと微調整して、別のMatrixオブジェクト内にMatrixが存在するのを完全に避けることができると思います。代わりに、動的に割り当てられた行列へのポインタを持つと考えましたか?これにより、プログラムのコピー量が大幅に削減され、プログラムのメモリと実行時の効率が大幅に向上します。

希望すると便利です。