Bee*_*ope 4 c++ macros c-preprocessor
想象一下,我有一个X宏,用于定义如下内容的项目列表:
#define X_MACRO(FN) \
FN(foo) \
FN(bar) \
FN(zip)
Run Code Online (Sandbox Code Playgroud)
这很好用,我可以调用它来生成为每个元素模板化的相同代码,例如:
#define xstr(s) str(s)
#define str(s) #s
#define PRINT_X(E) void print_ ## E () { std::cout << str(E); };
X_MACRO(PRINT_X)
Run Code Online (Sandbox Code Playgroud)
这会void print_foo() { std::cout << "foo"; };
为每个X_MACRO元素生成类似的函数.到现在为止还挺好.
但是,现在,我希望X宏元素列表以预处理器宏为条件.例如,zip
元素应仅包含在X宏中(如果USE_ZIP
已定义).当然,我不能把#ifdef
X宏放在里面,比如:
#define X_MACRO(FN) \
FN(foo) \
FN(bar) \
#ifdef USE_ZIP
FN(zip)
#endif
Run Code Online (Sandbox Code Playgroud)
我可以改为将列表写两次,一次使用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
Run Code Online (Sandbox Code Playgroud)
...但是这违反了DRY,更重要的是,如果你需要有条件地包含其他元素,它会迅速失控,这需要为每个可能的USE_*
宏组合提供一个列表.
我怎样才能以合理的方式做到这一点?
一种方法是以基本样式拆分事物并从超级宏调用它(我不知道它们是否具有特殊名称):
#define X_MACRO_BASE(fn) \
fn(foo) \
fn(bar) \
#if USE_ZIP
#define X_MACRO(fn) \
X_MACRO_BASE(fn) \
fn(zip)
#else
#define X_MACRO(fn) \
X_MACRO_BASE(fn)
#endif
Run Code Online (Sandbox Code Playgroud)
它并不完美,但它仍然可能有用:-)
另一个巧妙的技巧是有一个简单的条件宏(比如说USE_ZIP
是0
或1
):
#define IF(cond, foo) IF_IMPL(cond, foo)
#define IF_IMPL(cond, foo) IF_ ## cond (foo)
#define IF_0(foo)
#define IF_1(foo) foo
Run Code Online (Sandbox Code Playgroud)
然后你可以说:
#define X_MACRO(fn) \
fn(foo) \
fn(bar) \
IF(USE_ZIP, fn(zip))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
571 次 |
最近记录: |