X宏中元素的条件定义 [英] Conditional definition of elements in an X Macro

查看:76
本文介绍了X宏中元素的条件定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下,我有一个 X宏,其中包含类似以下内容的项目列表:

Imagine I have an X Macro for a list of items defined something like this:

#define X_MACRO(FN) \
  FN(foo) \
  FN(bar) \
  FN(zip)

这很好用,我可以调用它为每个元素生成模板化的相同代码,例如:

This works great and I can call it to generate the same code templatized for each element, like:

#define xstr(s) str(s)
#define str(s) #s
#define PRINT_X(E) void print_ ## E () { std::cout << str(E); }; 
X_MACRO(PRINT_X)

这将为每个X_MACRO元素生成类似void print_foo() { std::cout << "foo"; };的函数.到目前为止,一切都很好.

This generates functions like void print_foo() { std::cout << "foo"; }; for each of the X_MACRO elements. So far, so good.

但是,现在,我希望X Macro元素列表以预处理器宏为条件.例如,只有在定义USE_ZIP的情况下,zip元素才应包括在X宏中.当然,我不能在X宏中放入#ifdef,例如:

Now, however, I want the list of X Macro elements to be conditional on a pre-processor macro. For example the zip element should only be included in the X Macro if USE_ZIP is defined. Of course, I can't put an #ifdef inside the X Macro, like:

#define X_MACRO(FN) \
  FN(foo) \
  FN(bar) \
#ifdef USE_ZIP
  FN(zip)
#endif

相反,我可以根据USE_ZIP将列表写两次,一次使用zip,一次不使用,如下所示:

I could instead write the list twice, once with zip and once without, based on the USE_ZIP like so:

#ifdef USE_ZIP
#define X_MACRO(FN) \
  FN(foo) \
  FN(bar) \
  FN(zip)
#else
#define X_MACRO(FN) \
  FN(foo) \
  FN(bar)
#endif

...但是这违反了DRY,更重要的是,如果您需要有条件地包含其他元素,则它会迅速失去控制,从而需要USE_*宏的每种可能组合的列表.

... but this violates DRY and more importantly it rapidly spirals out of control if you need to conditionally include other elements, which would require a list for each possible combination of USE_* macros.

我该如何以合理的方式做到这一点?

How can I do this in a reasonable way?

推荐答案

一种方法是将内容拆分为 base 样式,然后从超级宏调用它(我不知道如果它们有特殊名称):

One way to do this is to split things in a base style and call it from a super macro (I don't know if these have special names):

#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

这并不完美,但仍然可能有用:-)

It's not perfect, but it still might be useful :-)

另一个巧妙的技巧是拥有一个简单的条件宏(例如USE_ZIP0还是1):

Another neat trick is to have a simple conditional macro (say if USE_ZIP was 0 or 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

那么你可以说:

#define X_MACRO(fn) \
    fn(foo) \
    fn(bar) \
    IF(USE_ZIP, fn(zip))

这篇关于X宏中元素的条件定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆