这个C宏是什么意思?
what is the meaning of this C macro?
这是一个可以计算参数个数的宏。代码如下:
#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
和
Y_TUPLE_SIZE_PREFIX_ ## __VA_ARGS__ ## _Y_TUPLE_SIZE_POSTFIX
?
顺便说一句,我知道##(pound, pound) 的用法和#define 的机制Y_TUPLE_SIZE_I
PREFIX 和 POSTFIX 宏旨在使它在没有给出参数时给出 0,即 MPL_ARGS_SIZE()
。在这种情况下,Y_TUPLE_SIZE_PREFIX_
和 _Y_TUPLE_SIZE_POSTFIX
连接起来产生 Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX
,这会强制结果为 0。
在一般情况下,__VA_ARGS__
是 non-empty,因此串联只是扩展到与给定的相同数量的参数。接下来是 32, ... 0.
在这两种情况下,参数都用括号括起来。 Y_TUPLE_SIZE_II
去掉这些额外的括号并将参数传递给 Y_TUPLE_SIZE_I
。 Y_TUPLE_SIZE_I
仅扩展到其第 33 个参数,丢弃其余参数。
所以如果你给它 32 个参数,这 32 个参数将被跳过,后面的数字 32 将是所需的结果。如果你给它 31 个参数,它将跳过这 31 个,以及后面的第一个数字,即 32,结果将是下一个数字 31,同样是所需的。
如果你给它一个参数,它会跳过那个参数和它后面的 31,结果就是 1。
如果不给它任何参数,Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX
的特殊情况将发挥作用,即 32 个空参数后跟 0。这 32 个空参数将被跳过,结果将为 0。
没有参数的特殊情况的原因是没有它,它的行为与 one-argument 情况相同。以下内容可能有助于更好地理解它:
#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))
这是原始的宏集,但删除了对零参数的所有 special-case 处理。它适用于除 zero-argument 情况之外的所有情况,returns 1 而不是 0.
为了处理零参数,它将参数列表夹在前缀和后缀宏之间。如果结果扩展为 Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX
,则参数列表为空,特殊情况开始发挥作用。
这是一个可以计算参数个数的宏。代码如下:
#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
和
Y_TUPLE_SIZE_PREFIX_ ## __VA_ARGS__ ## _Y_TUPLE_SIZE_POSTFIX
?
顺便说一句,我知道##(pound, pound) 的用法和#define 的机制Y_TUPLE_SIZE_I
PREFIX 和 POSTFIX 宏旨在使它在没有给出参数时给出 0,即 MPL_ARGS_SIZE()
。在这种情况下,Y_TUPLE_SIZE_PREFIX_
和 _Y_TUPLE_SIZE_POSTFIX
连接起来产生 Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX
,这会强制结果为 0。
在一般情况下,__VA_ARGS__
是 non-empty,因此串联只是扩展到与给定的相同数量的参数。接下来是 32, ... 0.
在这两种情况下,参数都用括号括起来。 Y_TUPLE_SIZE_II
去掉这些额外的括号并将参数传递给 Y_TUPLE_SIZE_I
。 Y_TUPLE_SIZE_I
仅扩展到其第 33 个参数,丢弃其余参数。
所以如果你给它 32 个参数,这 32 个参数将被跳过,后面的数字 32 将是所需的结果。如果你给它 31 个参数,它将跳过这 31 个,以及后面的第一个数字,即 32,结果将是下一个数字 31,同样是所需的。
如果你给它一个参数,它会跳过那个参数和它后面的 31,结果就是 1。
如果不给它任何参数,Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX
的特殊情况将发挥作用,即 32 个空参数后跟 0。这 32 个空参数将被跳过,结果将为 0。
没有参数的特殊情况的原因是没有它,它的行为与 one-argument 情况相同。以下内容可能有助于更好地理解它:
#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))
这是原始的宏集,但删除了对零参数的所有 special-case 处理。它适用于除 zero-argument 情况之外的所有情况,returns 1 而不是 0.
为了处理零参数,它将参数列表夹在前缀和后缀宏之间。如果结果扩展为 Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX
,则参数列表为空,特殊情况开始发挥作用。