这个C宏是什么意思?

这个C宏是什么意思?,c,macros,C,Macros,下面是一个可以计算参数计数的宏。代码如下: #define Y_TUPLE_SIZE_II(__args) Y_TUPLE_SIZE_I __args #define Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0 #define Y_TUPLE_SIZE_I(__p0,__p1,__p2,__p3,__p4,__p5,__p6,__p7,__p8,__p9,__p10,__p11,__p1

下面是一个可以计算参数计数的宏。代码如下:

#define Y_TUPLE_SIZE_II(__args) Y_TUPLE_SIZE_I __args
#define Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0

#define Y_TUPLE_SIZE_I(__p0,__p1,__p2,__p3,__p4,__p5,__p6,__p7,__p8,__p9,__p10,__p11,__p12,__p13,__p14,__p15,__p16,__p17,__p18,__p19,__p20,__p21,__p22,__p23,__p24,__p25,__p26,__p27,__p28,__p29,__p30,__p31,__n,...) __n

#define MPL_ARGS_SIZE(...) Y_TUPLE_SIZE_II((Y_TUPLE_SIZE_PREFIX_ ## __VA_ARGS__ ## _Y_TUPLE_SIZE_POSTFIX,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))

// the running result ---------------------------------------

MPL_ARGS_SIZE(a,b,c,d,e,f,g)==7

MPL_ARGS_SIZE(a,b,c,d)==4
如何理解

#define Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0

?


顺便说一句,我知道###(pound,pound)的用法和#define Y TUPLE_SIZE_I

前缀和后缀宏的目的是在没有参数的情况下使其为0,即
MPL_ARGS_SIZE()
。在这种情况下,
Y\u TUPLE\u SIZE\u PREFIX\u
\u Y\u TUPLE\u SIZE\u POSTFIX
被连接起来以产生
Y\u TUPLE\u SIZE\u PREFIX\u Y\u TUPLE\u SIZE\u POSTFIX,这将强制结果为0

在一般情况下,
\uu VA\u ARGS\uu
是非空的,因此连接只会扩展到给定的相同数量的参数。然后是32。。。0

在这两种情况下,参数都用括号括起来
Y\u TUPLE\u SIZE\u II
去掉这些额外的括号,并将参数传递给
Y\u TUPLE\u SIZE\u I
Y\u TUPLE\u SIZE\u I
仅扩展到其第33个参数,丢弃其余参数

因此,如果您给它32个参数,那么这32个参数将被跳过,并且它们后面的数字32将是所需的结果。如果您给它31个参数,它将跳过这31个参数,并跳过后面的第一个数字,即32,结果将是下一个数字,31,这也是所需的

如果给它一个参数,它将跳过该参数和它后面的31个参数,结果将是1

如果您不给它任何参数,那么
Y\u TUPLE\u SIZE\u PREFIX\u Y\u TUPLE\u SIZE\u POSTFIX
的特例将起作用,即32个空参数后跟0。将跳过32个空参数,结果为0

无参数特殊情况的原因是,如果没有它,它的行为将与单参数情况相同。以下内容可能有助于更好地理解它:

#define Y_TUPLE_SIZE_II(__args) Y_TUPLE_SIZE_I __args
#define Y_TUPLE_SIZE_I(__p0,__p1,__p2,__p3,__p4,__p5,__p6,__p7,__p8,__p9,__p10,__p11,__p12,__p13,__p14,__p15,__p16,__p17,__p18,__p19,__p20,__p21,__p22,__p23,__p24,__p25,__p26,__p27,__p28,__p29,__p30,__p31,__n,...) __n

#define MPL_ARGS_SIZE(...) Y_TUPLE_SIZE_II((__VA_ARGS__,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
这是原始的宏集,但删除了所有针对零参数的特殊情况处理。它适用于除零参数情况外的所有情况,零参数情况返回1而不是0


为了处理零参数,它将参数列表夹在前缀宏和后缀宏之间。如果结果扩展为
Y\u TUPLE\u SIZE\u PREFIX\u\u Y\u TUPLE\u SIZE\u POSTFIX
,则参数列表为空,特例开始发挥作用。

这是一组非常疯狂的宏…您只是在形成一组要传递的空参数(和0)。连接这些参数后,将得到一个参数列表。不过,这似乎比参数计数器宏所需的略多。我猜您所问的宏可能处理了
MPL\u ARGS\u SIZE()
的情况,给出0而不是1。@chris否,只有在没有给出参数的情况下,空参数才起作用。这是个特例。在正常情况下,没有空参数。@TomKarzes,这就是我最后一句话的意思。在构建越来越多的心智模型时,该评论是结构化的。我在下面扩展了我的答案,以包括一个精简的解决方案,该解决方案排除了零参数的特殊情况(因此该情况下的结果是1而不是0)。这应该使它更容易理解。好吧,方法
Y\u TUPLE\u SIZE\u II(((\u VA\u ARGS\u,32…0))
更容易理解。回到<代码>但回到<代码>但又回到<代码>上,定义了MPL\U ArguU Argus(U)码>上,定义了<代码>上,定义了<代码>上,定义了MPL\U U Argus(U)尺寸尺寸(…)Y)Y)的元元组(U)的元组(U)定义了你你的元组(U)的尺寸尺寸尺寸大小大小(U)的大小(U)你)的U U U U U U U U尺寸(U)的元元组(U尺寸大小大小(U尺寸)的大小(((…)Y)Y)Y)Y)Y)Y)Y)Y)Y)Y)Y U元元元组(U元元组(U U U U U U U U TuTuTuTuTuTuTupuU大小(U大小大小(U大小大小大小(U大小大小(U大小大小大小)大小(U大小(U大小(U大小(U大小大小)大小)大小)的大小(U元组大小后缀,…0))
,当然这是一个错误的语句,如何理解它?对,在一个或多个参数的情况下,第一个和最后一个参数会被前缀和后缀字符串更改,但这并不重要,因为参数的唯一用途是占据参数位置。它们在最终结果中都会被丢弃。哦,我是在…之前丢失。
Y TUPLE\u SIZE\u II((Y TUPLE\u SIZE\u PREFIX\u a,b,c\u Y TUPLE\u SIZE\u POSTFIX,…0)
将扩展为
Y TUPLE\u SIZE\u I(Y TUPLE\u SIZE\u PREFIX\u a,b,c\u Y TUPLE\u SIZE\u POSTFIX,…0)
,前缀\u a,b,c\u POSTFIX都作为
Y TUPLE\u SIZE\u宏的参数。
#define Y_TUPLE_SIZE_II(__args) Y_TUPLE_SIZE_I __args
#define Y_TUPLE_SIZE_I(__p0,__p1,__p2,__p3,__p4,__p5,__p6,__p7,__p8,__p9,__p10,__p11,__p12,__p13,__p14,__p15,__p16,__p17,__p18,__p19,__p20,__p21,__p22,__p23,__p24,__p25,__p26,__p27,__p28,__p29,__p30,__p31,__n,...) __n

#define MPL_ARGS_SIZE(...) Y_TUPLE_SIZE_II((__VA_ARGS__,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))