Macros C预处理器,宏“;超载“;

Macros C预处理器,宏“;超载“;,macros,c-preprocessor,variadic-macros,boost-preprocessor,Macros,C Preprocessor,Variadic Macros,Boost Preprocessor,我试图做一些宏“重载”,这样宏(某物)的展开方式就不同于宏(某物)了 使用我从boostpp库中获得的一个片段(我不确定它是否100%可移植)和一些函数,我能够使它工作: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) //TH

我试图做一些宏“重载”,这样宏(某物)的展开方式就不同于宏(某物)了

使用我从boostpp库中获得的一个片段(我不确定它是否100%可移植)和一些函数,我能够使它工作: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)
现在我仍然缺少另外两件我想做的事情:

  • (这一个我真的不在乎我是否从未解决过)我相信可以编写一个宏,当使用“变体”的数量及其相应的“输出”时,生成类似于上面的代码。类似于模板(3,函数_A(…)、函数_B(…)、函数_C(…)来生成上面的示例

  • 如果在没有参数的情况下调用TEST()会发生什么?那么,瓦努纳格斯扩展到1。但第一个参数是“”(无)。我试图找到一种方法来检测
    中的'zero'参数,或者区分'null'参数和真实参数,以便扩展'overloading'函数来应对这种情况。有什么想法吗


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

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

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


    < C++ >强:>包同时发布,包含大量的宏“重载”和类型通用宏。< /P> Boost -C++>如果你已经使用C++,不要乱用预处理器,使用简单函数(如果你愿意的话,请内联)。C预处理器故意是哑的,这样人们就不会滥用它。这是C还是C++?还要注意的是,在宏中使用varargs是不可移植的。@Paul R:可变宏是C99的一部分。@Jens:谢谢你指出这一点-如果你想以MSVC为目标,它们仍然是不可移植的,因为Microsoft仍然不支持C99。@Paul。MSVC不支持C99,但它们确实支持
    \uuu-VA\u-ARG\uuuu
    \uu-VA\u-ARG\uuu>,
    (2008 express)Boost迭代器宏有几种不同类型的序列:List
    (a(b(c,d))
    ,tuples
    (a,b,c)
    (长度必须已知)和List
    (a)(b)(c)
    。后者对我来说是最容易处理的。