C预处理器,宏“重载”

时间:2010-08-06 01:40:43

标签: macros c-preprocessor variadic-macros boost-preprocessor

我正在尝试做某种宏“重载”,因此MACRO(某些东西)的扩展方式与MACRO不同(其他东西)。

使用我从here得到的片段(我不确定它是否100%便携)以及Boost PP库中的一些功能,我能够使其工作:D

//THESE TWO COUNT THE NUMBER OF ARGUMENTS
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)

//THIS ONE RETURNS THE PARAMETER AT POSITION _i FROM A LIST OF __VA_ARGS__
#define VA_ARG(_i, ...) BOOST_PP_ARRAY_ELEM(_i, (VA_NARGS(__VA_ARGS__), (__VA_ARGS__)))

//AND THIS ONE IS THE 'OVERLOADED' MACRO ;)
#define TEST(...) BOOST_PP_IF(BOOST_PP_EQUAL(1, VA_NARGS(__VA_ARGS__)), function_A(VA_ARG(0, __VA_ARGS__)), \ //1 parameter
                  BOOST_PP_IF(BOOST_PP_EQUAL(2, VA_NARGS(__VA_ARGS__)), function_B(VA_ARG(0, __VA_ARGS__) + VA_ARG(1, __VA_ARGS__)), \ //2 parameters
                  BOOST_PP_IF(BOOST_PP_EQUAL(3, VA_NARGS(__VA_ARGS__)), function_C(VA_ARG(1, __VA_ARGS__) + VA_ARG(2, __VA_ARGS__)), BOOST_PP_EMPTY())) // 3 parameters and so on ...

So       TEST(a) = function_A(a)
      TEST(a, b) = function_B(a + b)
   TEST(a, b, c) = function_C(b + c)

现在我还缺少其他两件我想做的事情:

  1. (这个我真的不在乎,如果我从来没有解决过它)我相信可以写出一个MACRO,当占用'变种'的数量时,其对应的'输出'会生成类似的代码上面的一个。像TEMPLATE(3,function_A(...),function_B(...),function_C(...))之类的东西来生成上面的例子。

  2. 在没有参数的情况下调用TEST()会发生什么?好吧,VA_NARGS扩展为1.但第一个参数是“”(没有)。我试图找到一种方法来检测__VA_ARGS__中的'零'参数,或者区分'null'参数和真实参数,以扩展'重载'函数以对这种情况作出反应。有什么想法吗?

1 个答案:

答案 0 :(得分:5)

首先回答你的问题2。是的,对于可变参数宏,还可以检测空参数列表。解释有点冗长,我已经写了here。将此方法与您正在使用的增强宏结合起来应该相对容易。

对于你的问题1,是的,这也是可能的。我认为Boost有一些接近这个的迭代器宏,但它们看起来有点可怕。如果我理解正确,你必须使用嵌套列表(a, (b, (c,d)))之类的东西,不太方便。

(我写了一组可以更直接地实现这一点的宏, 但不幸的是,这个包还没有准备好发布。如果您真的对此感兴趣,请私下与我联系。)

编辑P99软件包同时发布,并且包含很多关于宏“重载”的内容并输入通用宏。