重载宏 [英] Overloading a macro

查看:88
本文介绍了重载宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试按参数数量重载宏.
当然,我实际上不能重载宏.

I'm trying to overload a macro by the number of parameter.
Of course I can't actually overload the macro.

我尝试使用可变参数宏选择正确的宏(使用以下事实:如果不存在__VA_ARGS__,则应该删除它之前的最后一个昏迷-

I've tried using variadic macros to choose the right macro (using the fact that if __VA_ARGS__ doesn't exist it's supposed to delete the last coma before it - GCC Reference):

#define TEST1() printf("TEST1");
#define TEST2() printf("TEST2");

#define CHOOSER(x, y,FUNC,...) FUNC()

#define MANIMACRO(...) CHOOSER(,__VA_ARGS__,TEST1,TEST2)

int main(void)
{
    MANIMACRO(1);
    MANIMACRO();
}

这个想法是,如果__VA_ARGS__存在,它应该将4个参数传递给 CHOOSER ,其中第三个参数应该与未使用的参数一起消失".因此将选择TEST1.

The idea was that if __VA_ARGS__ exists it should pass 4 arguments to CHOOSER, where the third one should have been "disappeared" with the unused args. so TEST1 would be chosen.

如果没有参数,__VA_ARGS__将为空,并且应该已经消除了昏迷,因此将选择并使用 TEST2 .

If there is no parameter the __VA_ARGS__ would be null, and should have removed the coma, so TEST2 would be chosen and used.

所以,我想这是行不通的,因为__VA_ARGS__可能只有在整个处理过程都已扩展之后的预处理阶段的最后才被删除.

So, i guess that doesn't work because the __VA_ARGS__ probably gets removed only at the end of the preprocessing stage, after the whole thing was already expanded.

那么,我该怎么做? (在vs2010中)

So, how can I do such a thing? (in vs2010)

推荐答案

基于此答案:

#define TEST1(expr)           printf("test1")
#define TEST2(expr, explain)  printf("test2")

#define N_ARGS_IMPL2(_1, _2, count, ...) \
   count
#define N_ARGS_IMPL(args) \
   N_ARGS_IMPL2 args
#define N_ARGS(...) N_ARGS_IMPL((__VA_ARGS__, 2, 1, 0))
 /* Pick the right helper macro to invoke. */
#define CHOOSER2(count) TEST##count
#define CHOOSER1(count) CHOOSER2(count)
#define CHOOSER(count)  CHOOSER1(count)
 /* The actual macro. */
#define TEST_GLUE(x, y) x y
#define TEST(...) \
   TEST_GLUE(CHOOSER(N_ARGS(__VA_ARGS__)), \
               (__VA_ARGS__))

int main() {
  TEST(one); // singleArgumentExpansion(one)
  TEST(two, "foopy"); // twoArgumentExpansion(two, "foopy")
  return 0;
}

这篇关于重载宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆