В конечном итоге я выбрал ответ Трэвиса, потому что его факторы еще более значимы, хотя, возможно, именно он был вдохновлен этим.
тавь, что у меня естьX Macro для списка элементов определено что-то вроде этого:
#define X_MACRO(FN) \
FN(foo) \
FN(bar) \
FN(zip)
Это прекрасно работает, и я могу вызвать его, чтобы сгенерировать один и тот же код для каждого элемента, например:
#define xstr(s) str(s)
#define str(s) #s
#define PRINT_X(E) void print_ ## E () { std::cout << str(E); };
X_MACRO(PRINT_X)
Это генерирует функции, такие какvoid print_foo() { std::cout << "foo"; };
для каждого из элементов X_MACRO. Все идет нормально.
Однако теперь я хочу, чтобы список элементов X Macro был обусловлен макросом препроцессора. Например,zip
элемент должен быть включен в X Macro, только еслиUSE_ZIP
определено. Конечно, я не могу положить#ifdef
внутри макроса X, например:
#define X_MACRO(FN) \
FN(foo) \
FN(bar) \
#ifdef USE_ZIP
FN(zip)
#endif
Я мог бы вместо этого написать список дважды, один раз сzip
и один раз без, на основеUSE_ZIP
вот так:
#ifdef USE_ZIP
#define X_MACRO(FN) \
FN(foo) \
FN(bar) \
FN(zip)
#else
#define X_MACRO(FN) \
FN(foo) \
FN(bar)
#endif
... но это нарушает СУХОЕ и, что более важно, оно быстро выходит из-под контроля, если вам необходимо условно включить другие элементы, для которых потребуется список для каждой возможной комбинацииUSE_*
макросы.
Как я могу сделать это разумным способом?