C预处理器,宏“重载”

4
我正在尝试进行一种宏“重载”,以便MACRO(something)和MACRO(something,else)的扩展方式不同。
我使用从这里获取的代码片段(我不确定它是否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. (如果我永远不解决这个问题,我真的不在意)我相信可以编写一个宏,当它接收到“变量”的数量及其对应的“输出”时,生成类似上面示例的代码。例如,TEMPLATE(3, function_A(...), function_B(...), function_C(...))生成如上所示的代码。

  2. 当没有参数调用TEST()会发生什么?好吧,VA_NARGS会扩展为1。但第一个参数是""(空白)。我正在尝试找到一种方法,要么检测__VA_ARGS__中的'零'参数,要么区分'空'参数和实际参数,以便将'重载'函数扩展到响应此情况。有任何想法吗?


2
Boost -> C++ -> 如果您已经在使用C ++,请不要搞乱预处理器,使用普通函数(如果需要,可以内联)。C预处理器故意很笨,以便人们不会滥用它。 - Dummy00001
这是用于C还是C++?另外请注意,在宏中使用可变参数不具有可移植性。 - Paul R
1
@Paul R:可变参数宏是C99的一部分。 - Jens Gustedt
@Jens:感谢您指出这一点-但是,如果您想针对例如MSVC,它们仍然不可移植,因为微软仍然不支持C99。 - Paul R
@PaulсђѓMSVCСИЇТћ»ТїЂC99№╝їСйєт«ЃС╗гТћ»ТїЂ__VA_ARG__тњї__VA_ARG__,№╝ѕ2008 express№╝Ѕсђѓ - KitsuneYMG
我并没有使用C ++,而是只是在为C使用Boost PP库。 - Ale Morales
1个回答

5
回答你的第二个问题。是的,使用可变参数宏也可以检测空参数列表。解释有点冗长,我已经写在了这里。结合你正在使用的boost宏应该相对容易实现。
关于你的第一个问题,是的,这也是可能的。Boost有一些迭代器宏看起来很接近,但使用起来有点可怕。如果我理解正确,你必须使用像嵌套列表(a, (b, (c,d)))之类的东西,不太方便。
(我编写了一组宏,可以更直接地实现此目标,但不幸的是该软件包尚未准备好发布。如果您真的对此感兴趣,请私下与我联系。) 编辑:P99软件包现在已发布,其中包含大量有关宏“重载”和类型通用宏的内容。

1
Boost迭代器宏有几种不同类型的序列:列表 (a (b (c,d) ) )、元组 (a,b,c)(长度必须已知)和列表 (a)(b)(c)。后者对我来说最容易处理。 - KitsuneYMG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接