追加到__VA_ARGS__ [英] Appending to __VA_ARGS__

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

问题描述

我知道我能做到这一点:

I know I can do this:

#define MACRO(api, ...) \
  bool ret = api(123, ##__VA_ARGS__);

这仅仅是一个例子,这是一个更复杂的解决方案的一部分。问题的关键是,我需要可变数量的参数追加到第一123。
在##,使编译器带出123参数后面的逗号如果没有参数被传递到宏。

This is just an example, it's part of a more complicated solution. The point is that I need to append the variable number of arguments to the first 123. The ## makes the compiler strip out the comma after the 123 argument if no arguments were passed into MACRO.

但现在我要追加参数的API,像这样:

But now I want to append arguments to api, like so:

#define MACRO(api, ...) \
  bool ret = api(__VA_ARGS__##, 456);

Nocando。一种解决方案是有两个宏,万家乐和MACRO_V,再说了,让_V版本不处理任何参数。但是,有没有一种方法,使其与一个宏工作?

Nocando. One solution is to have two macros, MACRO and MACRO_V, say, and make the _V version not process any arguments. But is there a way to make it work with one macro?

推荐答案

是的,可以。下面最多支持4个参数,但它可以扩展平凡支持更多:

Yes, you can. The following supports up to 4 arguments, but it can be trivially expanded to support more:

#define MACRO(api, ...) \
    bool ret = api(__VA_ARGS__ VA_COMMA(__VA_ARGS__) 456)

/*
 * VA_COMMA() expands to nothing if given no arguments and a comma if
 * given 1 to 4 arguments.  Bad things happen if given more than 4
 * arguments.  Don't do it.
 */
#define VA_COMMA(...) GET_6TH_ARG(,##__VA_ARGS__,COMMA,COMMA,COMMA,COMMA,)
#define GET_6TH_ARG(a1,a2,a3,a4,a5,a6,...) a6
#define COMMA ,

/* EXAMPLES */
MACRO(foo)                       /* bool ret = foo( 456)              */
MACRO(foo,1)                     /* bool ret = foo(1 , 456)           */
MACRO(foo,1,2,3,4)               /* bool ret = foo(1,2,3,4 , 456)     */
/* uh oh, too many arguments: */
MACRO(foo,1,2,3,4,5)             /* bool ret = foo(1,2,3,4,5 5 456)   */
MACRO(foo,1,2,3,4,5,6)           /* bool ret = foo(1,2,3,4,5,6 5 456) */

这同样的伎俩用于:

  • count the number of arguments
  • expand differently depending on the number of arguments

VA_COMMA 围绕着它的参数( __ VA_ARGS __ )六个额外的参数:前(一个空的参数没有为空—它扔掉)和四个逗号和后空的参数

VA_COMMA surrounds its arguments (__VA_ARGS__) with six additional arguments: one empty argument before (doesn't have to be empty—it's thrown away) and four commas and an empty argument after.

这六个或更多参数传递给 GET_6TH_ARG ,其中,顾名思义,扩展到第六个参数。所有其他参数都将被丢弃。

These six or more arguments are passed to GET_6TH_ARG, which, as its name implies, expands to the sixth argument. All other arguments are discarded.

因此​​, MACRO(富)是这样展开:

Thus, MACRO(foo) is expanded like this:

step 0: MACRO(foo)
step 1: bool ret = foo( VA_COMMA() 456)
step 2: bool ret = foo( GET_6TH_ARG(,COMMA,COMMA,COMMA,COMMA,) 456)
step 3: bool ret = foo( 456)

MACRO(富,1)扩展这样的:

step 0: MACRO(foo,1)
step 1: bool ret = foo(1 VA_COMMA(1) 456)
step 2: bool ret = foo(1 GET_6TH_ARG(,1,COMMA,COMMA,COMMA,COMMA,) 456)
step 3: bool ret = foo(1 COMMA 456)
step 4: bool ret = foo(1 , 456)

MACRO(富,1,2)扩展这样的:

step 0: MACRO(foo,1,2)
step 1: bool ret = foo(1,2 VA_COMMA(1,2) 456)
step 2: bool ret = foo(1,2 GET_6TH_ARG(,1,2,COMMA,COMMA,COMMA,COMMA,) 456)
step 3: bool ret = foo(1,2 COMMA 456)
step 4: bool ret = foo(1,2 , 456)

MACRO(富,1,2,3,4,5)扩展这样的:

step 0: MACRO(foo,1,2,3,4,5)
step 1: bool ret = foo(1,2,3,4,5 VA_COMMA(1,2,3,4,5) 456)
step 2: bool ret = foo(1,2,3,4,5 GET_6TH_ARG(,1,2,3,4,5,COMMA,COMMA,COMMA,COMMA,) 456)
step 3: bool ret = foo(1,2,3,4,5 5 456)

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

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