Conditional definition of elements in an X Macro

谁说我不能喝 提交于 2019-12-01 19:50:37

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 :-)


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

Then you can say:

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

There are a lot of different approaches to this.

The first one that comes to mind is, instead of one X macro, have several X macros that are conditionally defined. Then have a master X macro that calls all of them. This might still give you reasonably clear code. However, it may scale up badly if the number of conditions is large.

The second one that comes to mind is, don't use X macros, use Boost::preprocessor instead. There are good things and bad things about this, here's an example of what it might look like:

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/seq/for_each.hpp>

#include <iostream>

#define CONDITION 0
// #define CONDITION 1

#define MY_FIRST_SEQ (foo)(bar)(baz)
#define MY_SECOND_SEQ BOOST_PP_IF(CONDITION, (zip), (quz))
#define MY_SEQ MY_FIRST_SEQ MY_SECOND_SEQ


// Now we adapt original example
// The parameters r, data need to be there but don't have to be used, see here:
// http://www.boost.org/doc/libs/1_62_0/libs/preprocessor/doc/ref/seq_for_each.html
#define STR(x) #x
#define PRINT_X(r, data, E) void BOOST_PP_CAT(print_, E) () { std::cout << STR(E); };


// Now do this where we would invoke the X_MACRO
BOOST_PP_SEQ_FOR_EACH(PRINT_X, _, MY_SEQ)

int main() {}

How about:

#ifdef USE_ZIP
#  define IF_ZIP(arg) arg
#else
#  define IF_ZIP(arg)
#endif

#define X_MACRO(MAC) \
  MAC(foo)           \
  MAC(bar)           \
  IF_ZIP(MAC(zip))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!