Thales P. Carvalho writes about this technique at http://www.codeproject.com/macro/metamacros.asp
In short, a metamacro is a macro that expands itself based on another passed-in macro definition.
At my place of work, we call them "fruit lists" because 1) we weren't smart or academic enough to call them metamacros, and 2) the introduction that we had to them was given using fruits as an example.
MetaMacros allow programmers using CeeLanguage or CeePlusPlus to practice OnceAndOnlyOnce in a few "new" ways. GenericProgramming can find some help with them, and most importantly (IMHO) they allow for a lot of CodeGeneration and boilerplate to go away. (I suppose that's the point of OAOO though.) I use them, or a variant of them, most frequently in adding reflection-like capabilities to classes; systems that "automatically" parse ExtensibleMarkupLanguage into C structures is possible, as is displaying those structures in a GraphicalUserInterface, with controls set up using these "reflected" names appropriately and choosing the correct type of edit control based on the type of the object. E.g., a color named "myColor" could show up in the editor, named "My Color", and with a color swatch connected to it (that brings up a color picker when clicked on, etc.). Numbers (integers or floats) could have an edit box and a spinner control or anything else that makes sense; the definition of your metamacros allows you to do whatever you want. At this point, I still prefer not passing the expanded macro in as a parameter, but rather redefine it over and over globally, but it really comes down to the needs of the application. -- TomPlunket
So, some code:
#define DAYS_OF_WEEK(mac_) mac_(Sunday) mac_(Monday) mac_(Tuesday) mac_(Wednesday) mac_(Thursday) mac_(Friday) mac_(Saturday) #define ENUM_DOW(day_) k ## day_ , enum DayOfWeek { DAYS_OF_WEEK(ENUM_DOW) }; #define STRING_DOW(day_) #day_ , const char* days[] = { DAYS_OF_WEEK(STRING_DOW) }; void DebugOutput(DayOfWeek dow) { printf("day %d is %s.\n", dow, days[dow]); } int main(int argc, char* argv[]) { DebugOutput(kTuesday); DebugOutput(kFriday); return 0; }This outputs:
day 2 is Tuesday. day 5 is Friday.
See also MetaMetaMacro