2016-12-30 23 views
3

私は行列を使用する必要があると私はintデータ型のため、たとえば、宣言のこの種を使用しています:C++ - カスタムマトリックス構造体

std::vector < vector <int>> my2Dvec(rows, vector <int> (cols)); 

しかし、今、私は、複数のデータ・タイプのためにそれを使用したいと思いますので、私は、このテンプレートを宣言:

template <typename T> 
struct matrix 
{ 
    int col, row; 
    std::vector <std::vector <T>> data; 

    matrix(int c, int r) : col(c), row(r), data(col, std::vector <T> (row)) 
    { 
     ; 
    } 
}; 

だから私はようとしてそれを使用することができますどのように私は(可能な場合)を使用することができ、今

matrix <int> m(10, 10); 
... 
m.data[1][2] = 0; 

m[i][j] = someValue; 

?どのようにそのような機能を実装するには?あなたはそれはあなたが結果を得るために再びoperator[]を使用することができた上でプロキシオブジェクトを返しますような方法でoperator[]を実装する必要が

int& operator[](std::size_t i) { return data[i]; } 
+0

あなたはこれに新しいですので、あなたが使用してそれを単純化したい場合があります()演算子は代わりに[]の演算子は2を持つ:ここで

はダックタイピングによるカプセル化を尊重する例ですパラメーター。つまり、単純にT&operator()(const uint x、const uint y){return data [x] [y];}、T operator()(const uint x、const uint y)const {return data [ x] [y];}、これはm(i、j)= someValue;のようなアクセスをもたらす。プロキシメソッドより読みやすいかもしれません。いずれにしても、サブベクトルを保護したい - m [i] .resize(3)は動作しません。そのため、すべての属性が構造ではなく非公開であるクラスとして、それを行うことができます。 – Aziuth

答えて

1


カプセル化のポイント。

これは、パブリック実装で構造体として宣言されているため、ここでカプセル化されていないため、このように使用できます。 matrixがその実装(通常のC++の方法)を隠している場合は、operator []を実装するRow<T>の型を宣言してください。これは、duck typing以上のもので、PythonやRubyなどの動的言語で使用されていても、C++でも役立ちます。

/* 
class Matrix represents a matrix 
operator[](int i) returns a reference to the ith Row 
Row is an internal type that simply defines the operator[](int j) to return 
the ith element in a Row (which is a T&) 
*/ 
template <typename T> 
class Matrix { 
    // implementation 
    int col, row; 
    typedef std::vector<T> Row; 

    std::vector<Row> data; 

public: // interface 
    Matrix(int c, int r): row(r), col(c), data(c, std::vector<T>(r)) {} 

    // allow to use matrix[i][j] 
    Row & operator[](int i) { 
     return data[i]; 
    } 
}; 
+0

構造体であるため抽象的なレベルでのみ(部分的に)動作するように指定する必要があります。これは、プライベートでベクトルを持つクラスであれば、カプセル化を破り、実装にリンクされている可能性のあるオペレータを使用してコードを作成します。 –

+0

私は@ChrisRに同意します。 Serge Ballestaの解決策は、問題を解決してくれるものではありません。 – paweldac

+0

@ChrisR .:あなたはこの破られた封筒です。しかし、明示的なProxyクラスがなければカプセル化が可能です。私の編集を見てください。 –

0

あなたは、配列の添字演算子を実装する必要があります。

例コード:operator []として

std::vector<T> & operator[](int i) { 
    return data[i]; 
} 

既にベクターに定義され、十分であろう:ちょうど行への参照を返す[]オペレータを実装する必要が

struct matrix 
{ 
    struct Proxy 
    { 
     std::vector<int>* vec; 

     Proxy(std::vector<int>* vec_) 
      : vec(vec_) 
     { 
     } 

     int& operator[](int index) 
     { 
      return (*vec)[index]; 
     } 
    }; 

    matrix(int c, int r) : col(c), row(r), data(c, std::vector<int>(r)) 
    { 
    } 

    Proxy operator[](int index) 
    { 
     return Proxy(&data[index]); 
    } 

    int col, row; 
    std::vector<std::vector<int>> data; 
}; 
+0

2次元アレイでは十分ではありません。 – paweldac

+0

@paweldac:これは一例です。対応するベクトルを返すか、ラッパーを作成する必要があります。 – erenon