2010-08-06 115 views
4

我想要做一些宏“重载”,以便MACRO(东西),得到不同于MACRO(东西,其他)的扩展。C预处理器,宏“重载”

使用一个片段,我从here了(我不知道这是否是100%便携式),并从升压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) 

我“M仍下落不明另外两个是我想要做的事情:

  1. (这一次我真的不关心,如果我从来没有解决这个问题)我相信,一个宏可以写成占用时的数'variants'和它的记者'输出'产生一个类似于上面的代码。像TEMPLATE(3,function_A(...),function_B(...),function_C(...))来产生上面的例子。

  2. 当没有参数调用TEST()时会发生什么?那么,VA_NARGS扩展为1.但第一个参数是“”(没有)。我试图找到一种方法来检测__VA_ARGS__中的“零”参数,或者区分“空”参数和真实参数,以便扩展“超载”功能以对此情况作出反应。有任何想法吗?

+0

如果可以的话投票提问! :) – almosnow 2010-08-06 02:23:20

+2

Boost - > C++ - >如果您已经在使用C++,请不要混淆预处理器,请使用普通函数(如果您希望内联)。 C预处理器故意哑巴,以免人们滥用它。 – Dummy00001 2010-08-06 04:21:37

+0

这是用于C还是C++?还要注意,使用可变参数和宏是不可移植的。 – 2010-08-06 06:01:25

回答

4

先回答你的问题2。是的,使用可变宏可以检测一个空的参数列表。解释有点冗长,我写了它here。将此方法与您正在使用的boost宏组合起来应该相对容易。

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

(我写了一组宏可在此更直接地实现, 可惜包还没有准备好发布。联系我私人如果你是真的感兴趣。)

编辑:P99包在同时发布,并包含了很多东西在宏“重载”和类型通用宏。

+1

Boost迭代器宏有几种不同的类型序列:列出'(a(b(c,d)))',元组'(a,b,c)'(长度必须是已知的)并列出'(a)(b)(c)'。后者对我来说是最容易处理的。 – KitsuneYMG 2010-08-06 17:59:03

+0

延斯,你摇滚,工作完美无缺:)。非常感谢! – almosnow 2010-08-06 22:26:09