Path: utzoo!attcan!uunet!brunix!sdm From: sdm@cs.brown.edu (Scott Meyers) Newsgroups: comp.lang.c++ Subject: Re: Multidimensional Arrays accessed with [] operator Keywords: Arrays, [] operator Message-ID: <44365@brunix.UUCP> Date: 3 Jul 90 21:56:43 GMT References: <13060@shlump.nac.dec.com> Sender: news@brunix.UUCP Reply-To: sdm@cs.brown.edu (Scott Meyers) Organization: Brown University Department of Computer Science Lines: 95 In article <13060@shlump.nac.dec.com> heintze.peewee.enet.dec.com (Sieg Heintze) writes: >storage (MO) disk. I needed a five dimenensional array of floats whose >dimensions would be determined at run time. I was also determined to access >the elements with the [] operator regardless of whether I was in a function or >not! >How can I efficiently overload [] for a five dimensional pseudo array. Here's a possibility: create a class ArrayIndex that holds all the indices of the array, then define operator[] in your array class to take a single argument of type ArrayIndex. You can then do bounds checking, etc., on the ArrayIndex object, plus you can use "natural" syntax for multidimensional array. In general, you write arrayObject[a,b,c,d,e] which constructs an object of type ArrayIndex from the a, then uses the comma operator of ArrayIndex to eat up the b, c, d, and e arguments and finish the "construction" of the ArrayIndex object. const MAX_DIMENSIONS = 10; // no array has more than 10 indices class ArrayIndex { private: int nextIndex; int indices[MAX_DIMENSIONS]; public: ArrayIndex(int i): nextIndex(0) { indices[nextIndex++] = i; } ArrayIndex& operator,(int i) { if (nextIndex < MAX_DIMENSIONS) indices[nextIndex++] = i; // else signal an error (too many indices) return *this; } int numIndices() { return nextIndex; } const int& operator[](int i) { return indices[i]; } }; class Int5DArray { private: int lowBounds[5]; int highBounds[5]; int *data; public: Int5DArray (int l0, int h0, int l1, int h1, int l2, int h2, int l3, int h3, int l4, int h4) { // check bounds for validity (i.e., hi >= li for 0<=i<=4), store // them in the appropriate places in lowBounds and highBounds, and // allocate memory for data } int& operator[](ArrayIndex i) { // if (i.numIindices != 5) // signal an error (wrong number of indices) // if ((i[0] < lowBounds[0]) || (i[0] > highBounds[0]) ...) // signal an error (index out of bounds) // return the appropriate data } }; With this approach you lose compile-time checking that the number of array indices in a use matches the number the array actually has, but the test is performed at runtime instead. You gain generality, and this approach can be nicely combined with parameterized types to give you generic multidiminsional arrays. Note that some people may object to overloading the comma operator, since it can really obscure things, but since the syntax you use here isn't legal with "normal" arrays, confusion shouldn't be too bad. Now to be totally truthful, I didn't check this code to make sure it works, but it does at least get through cfront without any errors. Presuming that it works (or can be made to work), it will certainly be more efficient than four levels of pseudo-arrays, but it still may not be efficient enough. I suspect you could write a class-specific operator new/delete to increase the speed of construction/destruction of ArrayIndex objects, since each is used only once. Scott sdm@cs.brown.edu