2016-03-23 36 views
0

Çok boyutlu parantezleri nasıl yükleyebilirim?Çok boyutlu parantezleri aşırı yükleme

Artık bir n nv boşlukta yer açmamı sağlayan bir sınıfa sahip olduğumu varsayalım. Örneğin:

int main() { 
    NSpaceVector nsv; // Assume initializes all to 0 
    nsv[2][4][7][4][0][7][6] = 2; 
    cout << nsv[2][4][7][4][0][7][6] << endl; //-> 2 
    cout << nsv[1][4][7][4][0][7][6] << endl; //-> 0 
    return 0; 
} 

Bunu derlemeye alınamıyor: Ben yapmak istiyorum ne

class NSpaceVector { 
    private: 
     int vectorSpace[8][8][8][8][8][8][8]; 
    public:   
     const NSpaceVector operator[][][][][][][](int i, int j, int k, int l, int m, int n, int p)const {return vectorSpace[i][j][k][l][m][n][p]; } 
     NSpaceVector operator[][][][][][][](int i, int j, int k, int l, int m, int n, int p) {return vectorSpace[i][j][k][l][m][n][p]; } 
} 
unsigned long & operator [](int i) {return registers[i];} 

ben şöyle bu konuma endeksi can böylece braket operatörünü aşırı olduğunu. Herhangi bir fikir? Thx, Keith: ^)

+3

C++ 'da böyle bir operatör olmadığından çok boyutlu bir parantez yükleyemezsiniz. Bunun yerine, bir tür proxy nesnesini döndürmek için tek bir parantez yüklemeniz gerekir; tek boyutlu bir parantezdeki her aşırı yüklenme, başka bir proxy ... vb. Döndüren ikinci bir endeksleme düzeyi anlamına gelir. – SergeyA

+0

Bunu “operator()': https://isocpp.org/wiki/faq/operator-overloading#matrix-array-of-array – user4581301

+1

ile gerçekleştirmenin daha iyi bir yolunu okuyun. Ya da alternatif olarak, farklı bir bağlantıyı bulun. sözdizimi. Nsv (1,2,3,4,5,6,7) 'veya' nsv [{1,2,3,4,5,6,7}] 'gibi. –

cevap

1

Herhangi bir fikrin var mı?

her seviye için operator[]() aşırı ve dönüş türleri başka operator[]() aşırı atalım tek seçenek var.


açıklamalarda belirtildiği gibi, bu tür genellikle çağrıyı operator() aşırı ile çözülmüştür:

int operator()(size_t dim1, size_t dim2, ... size_t dimn); 
+0

Bu cevap beni rahatsız ediyor. Bunu C++ 17 spesifikasyonuna ekleyebileceğimiz bir şans var mı? – kmiklas

+0

@kmiklas Gerçekleri söyleyerek sizi rahatsız ettiğim için üzgünüz. Hayır, C++ 17 spec AFAIK ile operatör aşırı yüklenme sözdiziminde hiçbir değişiklik olmayacak ve ben de bu konuyla ilgili olarak onu değiştirmek için C++ standart komitesini ikna edeceğinizden şüpheliyim. –

+0

@kmiklas zilch. Zaman makineniz yoksa, o zaman sonsuzdur. –

1

standart cevap sahip olmaktır her [] (den soldan sağa) için bir proxy dönmek iç içe geçmiş alt kümesini doğrulayın; sonuncusu, veriye gerçekten bir başvuru döndürür. Planınızda, üretimi otomatik hale getirmek için iç içe geçmiş türleri şablona göre en kolay yolu olacaktır.

template <size_t Width, size_t Depth, typename T=int> 
struct SubSpace; 

template <size_t Width, typename T> 
struct SubSpace<Width,0,T> { 
    std::array<T, Width> array; 

    T& operator[] (size_t i) { return array[i]; } 
    T const& operator[] (size_t i) const { return array[i]; } 
}; 

template <size_t Width, size_t Depth, typename T> 
struct SubSpace { 
    using Nested = SubSpace<Width, Depth-1, T>; 
    std::array<Nested, Width> array; 

    Nested& operator[] (size_t i) { return array[i]; } 
    Nested const& operator[] (size_t i) const { return array[i]; } 
}; 


using NSpaceVector = SubSpace<8,6>; 

int main() 
{ 
    NSpaceVector nsv; 
    nsv[2][4][7][4][0][7][6] = 2; 
    cout << nsv[2][4][7][4][0][7][6] << endl; //-> 2 
} 

Not:

gizemli user4581301 Metni istenen sınıfın

nsv(2,4,7,4,0,7,6) 

Numune şablon üretimi geçici vekil nesnesini kullanarak daha muhtemelen daha basittir sağlamak çok daha basittir, söz

olarak Bu, dizi üyelerini şu anda varsayılan olarak başlatmıyor, ancak yine de toplu başlatmayı kullanabiliriz:

NSpaceVector nsv {}; // value-initialize every element 
    nsv[2][4][7][4][0][7][6] = 2; 
    cout << nsv[2][4][7][4][0][7][6] << endl; //-> 2 
    cout << nsv[2][4][7][4][0][7][5] << endl; //-> 0 

Ayrıca Derinlik Bu üst düzey olarak sarmalayıcı ile temizlenmiş olabilir 0'a sonlanır beri SubSpace<8,6>, 8x7 İstediğin neden verir unutmayın, ancak bunun yerine Depth==1 üzerine sonlandırmak ve birisi başlatır zaman her şey ters gitmeye olması için isteksiz SubSpace<0,0> kaza ile.


basit olsa da, yine Sınıfındaki herhangi davranış istemenize bağlı şudur ki:

struct OtherSpaceVector { 
    int s[8][8][8][8][8][8][8]; 

    auto operator[] (size_t i) -> decltype(s[i]) { return s[i]; } 
}; 

int main() 
{ 
    OtherSpaceVector osv{}; 
    osv[2][4][7][4][0][7][6] = 2; 
    std::cout << osv[2][4][7][4][0][7][6] << '\n'; 
    std::cout << osv[2][4][7][4][0][7][5] << '\n'; 
} 

Bu Boyutlarını değiştirmek için zor ve şablon sürümden daha kırılgan hissediyor, ancak sağladığınız kullanım durumu için hala çalışıyor.