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.