I created a C++ type representing a configuration file, using a template with non-type const char * parameters.
One of the ways to do that is by having a vector of strings that name the parameters, and an enumerated type that indexes the vector, like this:
src/option/wroptnames.cc
#ifndef def_cc_wroptnames #define def_cc_wroptnames #include <string> #include <vector> /** WROptNames is a global constant, so that its address(es) can be used as template arguments */ std::vector <std::string> WROptNames = { "configfile", "configdir", "varlibdir" }; #endif // def_cc_wroptnames
src/option/wroptint.cc
enum WROptInt { configfile = 0, configdir = 1, varlibdir = 2 };
However, in order to keep the correspondence of names between the enum and the vector correct, the programmer must be very careful.
So it's safer to generate src/option/wroptint.cc
using gen_wroptint, the source of which is trivial, and left as an exercise to the reader ;)
The interesting point here is that generating source with a program that first must be compiled involving same source easily creates circular dependencies in Makefiles: wroptint.cc is generated using gen_wroptint, but a new wroptint.cc would merit rebuilding gen_wroptint as well. The fact that gen_wroptint is merely required to build wroptint.cc, but a newly built gen_wroptint does not imply that wroptint.cc needs to be rebuilt, can be conveyed to Make thusly:
src/option/wroptint.cc: src/option/wroptnames.cc | gen_wroptint ./gen_wroptint src/option/wroptint.cc
See “order-only prerequisites” under types of prerequisites in the Make manual.