If we have a function foo with a prototype:
bool foo(int x, int y);we want to be able to say:
f = foo;for a suitable declaration of f and then use f wherever we might use foo.
<return type> (* <var>)(<argument types>)as in:
bool (*f) (int, int);The notation looks like a function prototype, except *f appears in parentheses. Notation is a little confusing, but we can use typedefs to make it more clear:
typedef bool (* int_comparison_fun) (int,int);Now we can write:
int_comparison_fun f; f = foo;
void sort(int A[], size_t n, bool (*compare)(int,int)) { int min; size_t k,minIndex; for(k=0; k+1 < used; k++) { minIndex = k; min = data[k]; for(size_t j=k+1; j < used; j++) { if (compare(data[j],min)) { min = data[j]; minIndex = j; } } data[minIndex] = data[k]; data[k] = min; } }Using the typedef, this function can be declared as:
void sort(int A[], size_t n, int_comparison_fun compare);
List<int> L;We would like to be able to write C++ code that will create a coresponding list of the squares of those integers:
List<int> squareList(const List<int> L) { ListIter<int> iter(L); List<int> newList; for(; !iter.isEnd(); iter.advance()) { int i = iter.current(); newList.append(i * i); } return newList; }
List<int> map(const List<int> L, int (*f)(int)) { ListIter<int> iter(L); List<int> newList; for(; !iter.isEnd(); iter.advance()) newList.append(f(iter.current())); return newList; }
int square(int i) { return(i*i); } int dbl(int i) { return(2*i); }We can now write:
map(L, square); map(L, double);
template <class T> List<T>* map(const List<T>& source, T (*f)(T)) // maps a list to another list, applying f to each element { ListIter<T> iter(source); List<T> *newList = new List<T>; for(; !iter.isEnd(); iter.advance()) newList->append(f(iter.current())); return newList; }Note the use of pointers in the return type to avoid redundant copy construction.