2017-08-25 9 views
0

C++でヒープ上に一般的な多次元配列を定義したい場合、配列に連続したメモリを割り当てて、ベクトルのギザギザのベクトル)。ここで私はメモリに連続して配置された多次元配列の実装

cout << t({ 1, 1, 1 }) << endl; 

は醜い例えば、アレイにアクセスするためのインタフェースを好きではない、私の実装が

#include <iostream> 
#include <vector> 
#include <stdexcept> 

using namespace std; 

typedef vector<unsigned int> VUI; 

class Invalid_MDArray : public exception{ 
public: 
    char* what(){ 
     return "Array cannot be constructed "; 
    } 
}; 

template <class T> 
class MArray{ 
private: 
    VUI dsize; 
    VUI cumsize; 
    T* p; 
    unsigned int stot; 

public: 

    unsigned int size(){ return stot; } 
    unsigned int size(unsigned int i) { return dsize[i]; } 


    MArray(const VUI& a){ 


     stot = 1; 
     for (unsigned int i = 0; i<a.size(); i++){ 

      if (a[i] == 0) { 
       Invalid_MDArray o; 
       throw o; 
      } 

      stot = stot*a[i]; 

      dsize.push_back(a[i]); 
      cumsize.push_back(stot); 
     } 

     dsize.push_back(stot); 

     p = new T[stot]; 


    } 


    ~MArray(){ 

     delete[] p; 
    } 


    inline T& operator()(VUI&& a){ 

     if (a.size() != dsize.size() - 1) { 

      out_of_range o("Index is out of bound!"); 
      throw o; 

     } 

     unsigned int i = 0; 
     while (i<a.size()){ 
      if (a[i]>dsize[i] - 1) { 

       out_of_range o("Index is out of bound!"); 
       throw o; 
      } 
      i++; 
     } 

     unsigned int index = 0; 

     //  index=i+imax*j+imax*jmax*k 

     i = 0; 
     while (i<a.size()){ 

      if (i == 0) { 
       index = a[i]; 
      } 
      else { 
       index = index + a[i] * cumsize[i - 1]; 

      } 


      i++; 
     } 


     return p[index]; 
    } 

}; 


int main(){ 


    try{ 
     MArray<int> t({ 2, 2, 2 }); 
     t({ 1, 1, 1 }) = 10; 
     cout << t({ 1, 1, 1 }) << endl; 

     // I prefer accessing the elements like this -> cout<<t(1,1,1)<<endl; 

     MArray<int> tt({ 2, 0, 2 }); // OOPS! cannot construct this array! 
     cout << t.size()<<endl; 
     t({ 1, 2, 1 }) = 1000; //OOPS! outofbound exception! 
    } 
    catch (exception &e){ 
     cout << e.what() << endl; 
    } 

    getchar(); 
} 

です。

cout<<t(1,1,1);のように、より自然な方法で要素へのアクセスを向上させるために、これを別の方法で実装することはできますか?

答えて

0

私は車輪を再発明しません。迅速なGoogle検索では、すべての設計要件に適合する多次元配列ライブラリBoost.MultiArrayが明らかになりました。

私はこれが早すぎる最適化であるかどうかも尋ねます。あなたは本当にもっとスピードは必要ですか?ベクトルは本当に速いです。

+1

operator()は解の次元数ごとに定義する必要があり、多次元配列の全体点は実行時にカスタムの次元数を指定できるため解はありません。 – KjMag

+0

@KjMag正しいです。私はそれを私の答えから取り除いた。 –