C++ templates, of course, provide the language's support for generic programming. These templates can also be used for template metaprogramming. In other words, you can write a C++ metaprogram in C++.
This is clever, cool, and – in the right hands – can even be useful.
I'd be out of my depth even trying to discuss C++ template metaprogramming. Fortunately, there's a growing body of literature and example libraries covering the subject in some depth.
As mentioned in passing, C++ has a sophisticated templating facility which (amongst other things) makes metaprogramming possible without needing to step outside the language.
C++ also inherits the C preprocessor: a rather unsophisticated facility, but one which is equally ready for use by metaprogrammers. In fact, careful use of this preprocessor can allow you to create generic C algorithms and simulate lambda functions.
For example:
#define ALL_ITEMS_IN_LIST(T, first, item, ...) \
do { \
T * item = first; \
while (item != NULL) { \
__VA_ARGS__; \
item = item->next; \
} \
} while(0)
#define ALL_FISH_IN_SEA(first_fish, ...) \
ALL_ITEMS_IN_LIST(Fish, first_fish, fish, __VA_ARGS__)
The first macro, ALL_ITEMS_IN_LIST
, iterates through items in a linked list
and optionally performs some action on each of them. It requires that list
nodes are connected by a next pointer called next
. The second macro,
ALL_FISH_IN_SEA
, specialises the first: the node type is set to Fish *
and
the list node iterator is called fish
instead of item
.
Here's an example of how we might use it:
/**
* @brief Find Nemos
* @param fishes Linked list of fish
* @returns The number of fish in the list called Nemo
*/
int findNemo(Fish * fishes)
{
int count;
ALL_FISH_IN_SEA(fishes,
if (!strcmp(fish->name, "Nemo")) {
printf("Found one!\n");
++count;
}
);
return count;
}
Note how simple it is to plug a code snippet into our generic looping construct. I have used one of C99's variadic macros to do this (these are not yet part of standard C++, but some compilers may support them).
I hesitate to recommend using the preprocessor in this way for all the usual reasons. That said:
One final point: the inline
keyword (intentionally) does not require the
compiler to inline code. The preprocessor can do nothing but!
Copyright © 2005 Thomas Guest |