我正在尝试做某种宏“重载”,以便宏(某物)的扩展方式与宏(某物,其他)不同。
使用我从此处获得的片段(我不确定是否它是 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)
现在我仍然缺少我想做的另外两件事:
-
(这个我不太关心如果我从未解决它)我相信可以编写一个宏,当占用“变体”的数量及其相应的“输出”时,会生成类似于上面的代码。像 TEMPLATE(3, function_A(...), function_B(...), function_C(...)) 这样的东西来生成上面的示例。
-
当不带参数调用 TEST() 时会发生什么?嗯,VA_NARGS 扩展为 1。但第一个参数是“”(无)。我正在尝试找到一种方法来检测 __VA_ARGS__ 中的“零”参数或区分“空”参数和真实参数,以便扩展“重载”函数以做出反应这种情况。有什么想法吗?
I'm trying to do some kind of Macro "Overloading", so that MACRO(something), gets expanded differently than MACRO(something, else).
Using a snippet I got from here (I'm not sure if it's 100% portable) and some functions from the Boost PP Library, I was able to make it work :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)
Now I'm still missing two other things that I want to do:
-
(This one I don't really care if I never solve it) I believe that a MACRO can be written that when taking up the number of 'variants' and its correspondent 'output' generates a code similar like the one above. Something like TEMPLATE(3, function_A(...), function_B(...), function_C(...)) to generate the example above.
-
What happens when TEST() is called without arguments? Well, VA_NARGS expands to 1. But the first argument is ""(nothing). I'm trying to find a way to either detect 'zero' arguments in __VA_ARGS__
or to differentiate between a 'null' argument and a real one, in order to extend the 'overloading' function to react to this situation. Any ideas?
发布评论
评论(1)
先回答你的问题2。是的,使用可变参数宏,也可以检测到空参数列表。解释有点长,我已经写在这里。将此方法与您正在使用的 boost 宏结合起来应该相对容易。
对于你的问题1,是的,这也是可能的。我认为 Boost 有一些与此接近的迭代器宏,但它们看起来使用起来有点可怕。如果我理解正确的话,你必须使用类似嵌套列表
(a, (b, (c,d)))
的东西,不太方便。(我写了一组宏可以更直接地实现这一点,
但不幸的是,该软件包尚未准备好发布。如果您真的对此感兴趣,请私下联系我。)
编辑:P99 包同时发布,包含大量宏“重载”和类型通用宏的内容。
To answer your question 2 first. Yes, with variadic macros it is also possible to detect an empty argument list. The explanation is a bit lengthy, I have written it up here. It should be relatively easy to combine this approach with the boost macros that you are using.
For your question 1, yes this is also possible. Boost has some iterator macros that come close to this, I think, but they look a bit scary to use. If I understand correctly you have to use something like nested lists
(a, (b, (c,d)))
, not too convenient.(I wrote a set of macros that can achieve this more directly,
but unfortunately the package is not yet ready for release. Contact me in private if you are really interested in it.)
Edit: The P99 package is published in the mean time and contains a lot of stuff over macro "overloading" and type generic macros.