Есть ли способ в стандартном C - или с расширениями GNU - добавить материал в определение макроса? Например, , если макрос определен как
#define List foo bar
, могу ли я добавить bas
, чтобы он List
расширялся, как если бы я его определил
#define List foo bar bas
?
Я надеялся, что смогу сделать что-то вроде этого:
#define List foo bar bas
#define List_ Expand(List)
#undef List
#define List Expand(List_) quux
, но я не могу понять, как определить макрос Expand()
, чтобы он делал то, что я хочу.
Мотивация: Я играю с дискриминированными / помеченными профсоюзами по следующим линиям:
struct quux_foo { int x; };
struct quux_bar { char *s; };
struct quux_bas { void *p; };
enum quux_type {quux_foo, quux_bar, quux_bas};
struct quux {
enum quux_type type;
union {
struct quux_foo foo;
struct quux_bar bar;
struct quux_bas bas;
} t;
};
Я считаю, что это хорошее место для X-макроса.Если я определю макрос
#define quux_table X(foo) X(bar) X(bas)
, перечисление и структура могут быть определены таким образом, и никогда не выйдут из синхронизации:
#define X(t) quux_ ## t,
enum quux_type {quux_table};
#undef X
#define X(t) struct quux_ ## t t;
struct quux {
enum quux_type type;
union {quux_table} t;
};
#undef X
Конечно, структуры quux_*
могут выйтисинхронизации, поэтому я хотел бы сделать что-то вроде этого, только на законных основаниях:
struct quux_foo { int x; };
#define quux_table quux_table X(foo)
struct quux_bar { char *s; };
#define quux_table quux_table X(bar)
struct quux_bas { void *p; };
#define quux_table quux_table X(bas)
(Ну, то, что я действительно хочу сделать, это что-то вроде
member_struct(quux, foo) { int x; };
но я хорошо знаю, что макросы нельзя (пере) определять из макросов.)
Во всяком случае, это мой мотивирующий пример.Есть ли способ сделать это?
Примеры Boost.Preprocessor хороши, если вы можете показать мне, как заставить технику X-macro работать с этой библиотекой.