harold@fmrco (Harold Naparst) (12/15/90)
I am trying to write a function which will return the index of the smallest element of an array. I want the routine to work for any type array. That is, I don't want to write a separate routine for each type of array (real or double or integer). How can I do this ? I tried playing around with the GNU C typeof operator, but couldn't figure it out. Any ideas ? Harold Naparst (uunet!fmrco!harold) -- Harold Naparst (uunet!fmrco!harold) Fidelity Management Trust Co. (617)-570-2587 82 Devonshire St., #I40F The opinions expressed herein are not those Boston, MA 02109 of my employer.
maguire@sun.soe.clarkson.edu (Bill Maguire) (12/18/90)
In article <1990Dec15.015355.15683@fmrco> harold@fmrco (Harold Naparst) writes: >I am trying to write a function which will return the index >of the smallest element of an array. I want the routine >to work for any type array. That is, I don't want to write >a separate routine for each type of array (real or double or >integer). How can I do this ? I tried playing around with >the GNU C typeof operator, but couldn't figure it out. Any ideas ? >Harold Naparst Tw ways immediately pop to mind: 1) overload the function to take a real*, double* or integer*. You'll have to do some text editing to copy the code and replace the types but this is where templates come in. With templates you can write only one of the functions and the compiler will generate the completed function definitions as you use them. (This isn't entirely true in GNU g++ yet, there is a SED script, I believe, that given a template will generate the function definitions that you ask of it) 2) The problem with having the same "compiled code" work on an array of real, double, or integer is that these objects are in no way related through any hierarchy. So any call to the function cannot be resolved polymorphically at run time. To correct this create a hierarchy of Numbers with Number as an abstract base class. You will have to do a lot of work defining the operators between numbers as it will take two virtual calls to resolve the type of each operand. At this point you can create an Array of Number object. Now write the function to work on an Array of Number. This will be slower than the first example as a great deal of polymorphic calls will have to be made, but less compiled code will be generated. (Not really, as you have to add the code for your whole type hierarchy) Another "problem" with this solution is that the Arrays are no longer limited to one type, you could have Integers, Reals, and Doubles in the same list. Not quite what you want. However you could do some more work and define the classes Array of Integer, Array of Real, and Array of Double as subclasses of Array of Number. These class would have to know what to do if they were asked to set an element to the wrong type (i.e error), (Actually if you were using an overload operator[] and passing back a reference as an lvalue than this can be resolved in the Number class) but they could be implemented much more efficiently than a straight array of number. Now you have what you want. A lot of work though. Bill Maguire sun.soe.clarkson.edu She had so many chins, she looked like a piece of lisp code :-))))))
noren@dinl.uucp (Charles Noren) (12/19/90)
In article <MAGUIRE.90Dec17132020@sun.clarkson.edu> maguire@sun.soe.clarkson.edu (Bill Maguire) writes: >In article <1990Dec15.015355.15683@fmrco> harold@fmrco (Harold Naparst) writes: > >>I am trying to write a function which will return the index >>of the smallest element of an array. I want the routine >>to work for any type array. That is, I don't want to write >>a separate routine for each type of array (real or double or >>integer). How can I do this ? I tried playing around with >>the GNU C typeof operator, but couldn't figure it out. Any ideas ? > >>Harold Naparst > >Two ways immediately pop to mind: ...or you could wait until AT&T implements Parameterized Types, or use (AT YOUR OWN RISK) one of the C++ compilers that has a version Parameterized Types (e.g., the C++ that comes with ObjectStore OODBMS by Object Design, Inc). -- Chuck Noren NET: dinl!noren@ncar.ucar.edu US-MAIL: Martin Marietta I&CS, MS XL8058, P.O. Box 1260, Denver, CO 80201-1260 Phone: (303) 971-7930
scs@adam.mit.edu (Steve Summit) (12/19/90)
In article <1990Dec15.015355.15683@fmrco> harold@fmrco (Harold Naparst) writes: >I am trying to write a function which will return the index >of the smallest element of an array. I want the routine >to work for any type array. [Someone may well already have suggested this; I might have missed it because my news feed appears to be flakey.] Since the question was crossposted to comp.lang.c, here's the straight-C answer, which doesn't involve any mucking about with derived or generic types. The caller does, on the other hand, have to provide a comparison routine appropriate for the data type being searched. (Come to think of it, this probably isn't what Mr. Naparst was looking for at all. Oh, well, the technique is instructive, and understanding it helps avoid problems when using qsort and bsearch.) Given sometype array[SOMESIZE]; and int sometypecmp(void *p1, void *p2) { sometype *sp1 = (sometype *)p1; sometype *sp2 = (sometype *)p2; if(*sp1 < *sp2) return -1; else if(*sp1 == *sp2) return 0; else return 1; } (this could return *sp1 - *sp2 if overflow wasn't a problem, and might have to use more complicated relationals for nonarithmetic types), we can call findbiggest(array, SOMESIZE, sizeof(sometype), sometypecmp); where findbiggest is findbiggest(void *a, size_t n, size_t elsize, int (*cmp)(void*,void*)) { void *biggest = a; register int i; char *p2; /* not void * so can do pointer arithmetic */ for(i = 1, p2 = (char *)a + elsize; i < n; i++, p2 += elsize) { if((*cmp)(p2, biggest) > 0) biggest = p2; } return ((char *)biggest - (char *)a) / elsize; } (Actually, a more likely implementation, closer to bsearch, would return a pointer to the largest element, not the index.) Steve Summit scs@adam.mit.edu
platt@ndla.UUCP (Daniel E. Platt) (12/21/90)
In article <1990Dec15.015355.15683@fmrco>, harold@fmrco (Harold Naparst) writes: > > I am trying to write a function which will return the index > of the smallest element of an array. I want the routine > to work for any type array. That is, I don't want to write > a separate routine for each type of array (real or double or > integer). How can I do this ? I tried playing around with > the GNU C typeof operator, but couldn't figure it out. Any ideas ? > Hi, I think that you'd need to provide some sort of comparator function that will actually do the comparison between the various elements, and all you need to be able to do is pass the size of the data objects so that you can compute the comparison pointers. Example: int least_find(base, nel, size, compar) char *base; int nel, size; int (*compar)(); { int i, i_least; for (i = i_least = 0; i < nel; i++) if ((*compar)(base + i * size, base + i_least * size) < 0) i_least = i; return i_least; } Then, all you'd need to do is pass the function in compar that would handle the comparison between your two types, and which would yield a value > 0, = 0, or < 0 depending on which element was larger. /* a function that will compare two integers */ int comp(u, v) int *u, *v; { return (*v - *u); } /* ** a section of code that will find the smallest out of N elements of array ** ar[] of ints using comp(). */ least = least_find(ar, N, sizeof(int), comp); Hope this gives you more of a feel of how this has been handled in the past... Dan
rfg@NCD.COM (Ron Guilmette) (12/22/90)
In article <1990Dec15.015355.15683@fmrco> harold@fmrco (Harold Naparst) writes: > >I am trying to write a function which will return the index >of the smallest element of an array. I want the routine >to work for any type array. That is, I don't want to write >a separate routine for each type of array (real or double or >integer). How can I do this ? I tried playing around with >the GNU C typeof operator, but couldn't figure it out. Any ideas ? I see that there have been a few responses to this already, but I didn't see anyone actually give what I consider to be a `good' answer. The question was how to "write" a generic function to find the index of the smallest element of an array of an arbitrary type. The questioner did not say anything about actually needing to compile it into executable code with the help of any currently available C++ language processor. :-) :-) :-) Here is a solution: template<class T> unsigned smallest (T array[], unsigned array_size) throw (Range_Error) { T* smallest_value_p = &array[0]; unsigned smallest_index = 0; if (array_size == 0) throw Range_Error (Zero_Length); for (unsigned i = 1; i < array_size; i++) if (array[i] < *smallest_value_p) { smallest_value = &array[i]; smallest_index = i; } return i; } Won't life be beautiful when we can actually *use* templates & exceptions? -- // Ron Guilmette - C++ Entomologist // Internet: rfg@ncd.com uucp: ...uunet!lupine!rfg // Motto: If it sticks, force it. If it breaks, it needed replacing anyway.