我正在尝试做某种宏“重载”,以便宏(某物)的扩展方式与宏(某物,其他)不同。

使用我从中获得的片段 这里 (我不确定它是否 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 宏结合起来应该相对容易。

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

(我写了一组可以更直接实现的宏,但不幸的是,该软件包尚未准备好发布。如果有的话可以私信我 真的 有兴趣。)

编辑:P99 同时发布了软件包,其中包含许多超过宏“重载”和类型通用宏的内容。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top