heintze.peewee.enet.dec.com (Sieg Heintze) (07/04/90)
During Spring Semester, I was simulating the write path of a magnetic-optical 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! I wanted to create a special array class and overload the [] operator. As you may know, there is a serious problem with C and the default array syntax for C++. I refer you to page 120 of Stroustrup's "the C++ Programming Language" where he says you cannot pass arrays, you can only pass pointers and inside the recieving subprogram you have to compute your own offsets. Even Bjarne (in the comments) says that this is obscure! Someone kindly gave an example of using the [] operator to access a pseudo array. This what was done was to use [] to access an array of pointers. So for each successive dimension, you have another array of pointers. Each array of pointers is contained an a class that also holds the bounds for that row or column. Well this was very nice and even pratical for two dimensional arrays. But I was afraid to try it with a five dimensional pseudo array! The redundant overhead would be staggering! How can I efficiently overload [] for a five dimensional pseudo array. Better yet, how can I efficiently overload [] for a five dimensional real array (ie, an contiguous array that does not use pointers to find a element given the row and column). Incidently, for my simulation, I gave up on overloading [] and just used the features of C to access entity declared as "float**** modisk;". This did not, of course, have the bounds checking I wanted. heintze@genral.enet.dec.com Digital Equipment Corporation 1110 Chapel Hills Drive CXN2-2/35 Colorado Springs, CO 80920-3995 719-260-2184
sdm@cs.brown.edu (Scott Meyers) (07/04/90)
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