Есть ли какой-либо способ в стандартном 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 работать с этой библиотекой.
Да, это определенно выполнимо, если вы не настаиваете на переопределении. Несколько больно, если вы используете исходный препроцессор. Несколько менее болезненным с Boost.Preprocessor. Увы, мой холод мешал мне думать достаточно прямо, чтобы создать метод. Надеюсь, кто-то еще это сделает. – swestrup