【发布时间】:2017-05-14 17:01:14
【问题描述】:
我在我的项目中使用X Macros,以便在名称列表都需要对其执行相同操作(例如创建、初始化、填充和销毁)的地方使用not repeat myself。
由于我试图指定一次的数据涉及一些相同的宏翻译(忽略参数、前缀与后缀),我决定通过将它们重写为广义的 Meta X 来增强my original single-fit X Macros -宏,从中可以定义多个衍生的最终用例拟合 X 宏,使用解释元宏参数的转换宏:
// Meta-macros //
#define MAIN_WINDOW_TEXT_LAYERS_METAMACRO(macro, tr) \
macro(tr(hour_layer)) \
macro(tr(min_layer)) \
macro(tr(date_layer))
#define MAIN_WINDOW_LAYERS_METAMACRO(macro, tr) \
macro(tr(colon_layer)) \
macro(tr(phone_batt_layer)) \
macro(tr(watch_batt_layer))
#define GBITMAPS_WITH_RESOURCE_IDS_METAMACRO(macro, tr) \
macro(tr(watch_icon, ICON_WATCH_6X11)) \
macro(tr(watch_charging_icon, ICON_WATCH_CHARGING_6X11)) \
macro(tr(phone_icon, ICON_PHONE_6X11)) \
macro(tr(phone_charging_icon, ICON_PHONE_CHARGING_6X11))
#define GFONTS_WITH_RESOURCE_IDS_METAMACRO(macro, tr) \
macro(tr(time_font, FONT_ARVO_BOLD_48)) \
macro(tr(date_font, FONT_ARVO_BOLD_20))
// Transformation macros //
#define IDENTITY_MACRO(x) x
#define STATIC_PREFIX_MACRO(x) s_ ## x
#define STATIC_PREFIX_DISCARD_MACRO(x, _) s_ ## x
#define STATIC_PREFIX_RESOURCE_ID_PREFIX_MACRO(x, id) \
s_ ## x, RESOURCE_ID_ ## s
// Derived X-Macros //
#define FOR_MAIN_WINDOW_STATIC_TEXT_LAYER_POINTERS(macro) \
MAIN_WINDOW_TEXT_LAYERS_METAMACRO(macro, STATIC_PREFIX_MACRO)
#define FOR_MAIN_WINDOW_STATIC_LAYER_POINTERS(macro) \
MAIN_WINDOW_LAYERS_METAMACRO(macro, STATIC_PREFIX_MACRO)
#define FOR_MAIN_WINDOW_LAYER_NAMES(macro) \
MAIN_WINDOW_LAYERS_METAMACRO(macro, IDENTITY_MACRO)
#define FOR_STATIC_GFONTS(macro) \
GFONTS_WITH_RESOURCE_IDS_METAMACRO(macro, STATIC_PREFIX_DISCARD_MACRO)
#define FOR_STATIC_GFONTS_WITH_RESOURCE_IDS(macro) \
GFONTS_WITH_RESOURCE_IDS_METAMACRO(macro, STATIC_PREFIX_RESOURCE_ID_PREFIX_MACRO)
#define FOR_STATIC_GBITMAP_POINTERS_WITH_RESOURCE_IDS(macro) \
GBITMAPS_WITH_RESOURCE_IDS_METAMACRO(macro, STATIC_PREFIX_RESOURCE_ID_PREFIX_MACRO)
#define FOR_STATIC_GBITMAP_POINTERS(macro) \
GBITMAPS_WITH_RESOURCE_IDS_METAMACRO(macro, STATIC_PREFIX_DISCARD_MACRO)
这在大多数用例中都有效:但是,在少数极端情况下我会遇到麻烦。首先,尝试连接参数会导致 transformation 宏的名称 被连接,而不是 transformed 名称:
#define X(name) layer_set_update_proc(s_ ## name, name ## _update_proc);
FOR_MAIN_WINDOW_LAYER_NAMES(X)
#undef X
error: implicit declaration of function 's_IDENTITY_MACRO'
其次,转换两个参数的宏不会被扩展 - 它们被传递给 X 作为一个单个标记(对转换宏的调用):
#define X(name, id) name = fonts_load_custom_font(resource_get_handle(id));
FOR_STATIC_GFONTS_WITH_RESOURCE_IDS(X)
#undef X
error: macro "X" requires 2 arguments, but only 1 given error: unknown type name 'X'
#define X(name, id) name = gbitmap_create_with_resource(id);
FOR_STATIC_GBITMAP_POINTERS_WITH_RESOURCE_IDS(X)
#undef X
error: macro "X" requires 2 arguments, but only 1 given error: expected '=', ',', ';', 'asm' or '__attribute__' before 'X'
我怎样才能让这些按照我想要的方式工作?
【问题讨论】:
标签: c macros c-preprocessor