c/c++:for each遍历 __VA_ARGS__ 中的每一个元素

因为项目需要,要大量定义类似的枚举类型。

typedef enum test{
	test_1,test_2,test3....
}test;

手工写实在太多了,而且容易出错,于考虑用可变参数宏:__VA_ARGS__ 来实现,关键就是要实现对__VA_ARGS__中每个参数元素的遍历。
下面是现实代码,真正调用的宏只有一个FL_FOREACH
FL_FOREACH实现对__VA_ARGS__中的每个参数执行指定的函数宏funfun允许有一个外部输入参数funarg
类似于C++11 STL库中的for_each函数

代码中用到的FL_ARG_COUNT宏参见前一篇博客《c/c++:计算可变参数宏 __VA_ARGS__ 的参数个数》

// 参数拼接
#define FL_CONCAT_(l, r) l ## r

#define FL_CONCAT(l, r) FL_CONCAT_(l, r)

#define FL_DOARG0(s,f,a,o)
#define FL_DOARG1(s,f,a,v,...) f(a,v)
#define FL_DOARG2(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG1(s,f,a,__VA_ARGS__)
#define FL_DOARG3(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG2(s,f,a,__VA_ARGS__)
#define FL_DOARG4(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG3(s,f,a,__VA_ARGS__)
#define FL_DOARG5(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG4(s,f,a,__VA_ARGS__)
#define FL_DOARG6(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG5(s,f,a,__VA_ARGS__)
#define FL_DOARG7(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG6(s,f,a,__VA_ARGS__)
#define FL_DOARG8(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG7(s,f,a,__VA_ARGS__)
#define FL_DOARG9(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG8(s,f,a,__VA_ARGS__)
#define FL_DOARG10(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG9(s,f,a,__VA_ARGS__)
#define FL_DOARG11(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG10(s,f,a,__VA_ARGS__)
#define FL_DOARG12(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG11(s,f,a,__VA_ARGS__)
#define FL_DOARG13(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG12(s,f,a,__VA_ARGS__)
#define FL_DOARG14(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG13(s,f,a,__VA_ARGS__)
#define FL_DOARG15(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG14(s,f,a,__VA_ARGS__)
#define FL_DOARG16(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG15(s,f,a,__VA_ARGS__)
#define FL_DOARG17(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG16(s,f,a,__VA_ARGS__)
#define FL_DOARG18(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG17(s,f,a,__VA_ARGS__)
#define FL_DOARG19(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG18(s,f,a,__VA_ARGS__)
#define FL_DOARG20(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG19(s,f,a,__VA_ARGS__)
#define FL_DOARG21(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG20(s,f,a,__VA_ARGS__)
#define FL_DOARG22(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG21(s,f,a,__VA_ARGS__)
#define FL_DOARG23(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG22(s,f,a,__VA_ARGS__)
#define FL_DOARG24(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG23(s,f,a,__VA_ARGS__)
#define FL_DOARG25(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG24(s,f,a,__VA_ARGS__)
#define FL_DOARG26(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG25(s,f,a,__VA_ARGS__)
#define FL_DOARG27(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG26(s,f,a,__VA_ARGS__)
#define FL_DOARG28(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG27(s,f,a,__VA_ARGS__)
#define FL_DOARG29(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG28(s,f,a,__VA_ARGS__)
#define FL_DOARG30(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG29(s,f,a,__VA_ARGS__)
#define FL_DOARG31(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG30(s,f,a,__VA_ARGS__)
#define FL_DOARG32(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG31(s,f,a,__VA_ARGS__)
#define FL_DOARG33(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG32(s,f,a,__VA_ARGS__)
#define FL_DOARG34(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG33(s,f,a,__VA_ARGS__)
#define FL_DOARG35(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG34(s,f,a,__VA_ARGS__)
#define FL_DOARG36(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG35(s,f,a,__VA_ARGS__)
#define FL_DOARG37(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG36(s,f,a,__VA_ARGS__)
#define FL_DOARG38(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG37(s,f,a,__VA_ARGS__)
#define FL_DOARG39(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG38(s,f,a,__VA_ARGS__)
#define FL_DOARG40(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG39(s,f,a,__VA_ARGS__)
#define FL_DOARG41(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG40(s,f,a,__VA_ARGS__)
#define FL_DOARG42(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG41(s,f,a,__VA_ARGS__)
#define FL_DOARG43(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG42(s,f,a,__VA_ARGS__)
#define FL_DOARG44(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG43(s,f,a,__VA_ARGS__)
#define FL_DOARG45(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG44(s,f,a,__VA_ARGS__)
#define FL_DOARG46(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG45(s,f,a,__VA_ARGS__)
#define FL_DOARG47(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG46(s,f,a,__VA_ARGS__)
#define FL_DOARG48(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG47(s,f,a,__VA_ARGS__)
#define FL_DOARG49(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG48(s,f,a,__VA_ARGS__)
#define FL_DOARG50(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG49(s,f,a,__VA_ARGS__)
#define FL_DOARG51(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG50(s,f,a,__VA_ARGS__)
#define FL_DOARG52(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG51(s,f,a,__VA_ARGS__)
#define FL_DOARG53(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG52(s,f,a,__VA_ARGS__)
#define FL_DOARG54(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG53(s,f,a,__VA_ARGS__)
#define FL_DOARG55(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG54(s,f,a,__VA_ARGS__)
#define FL_DOARG56(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG55(s,f,a,__VA_ARGS__)
#define FL_DOARG57(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG56(s,f,a,__VA_ARGS__)
#define FL_DOARG58(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG57(s,f,a,__VA_ARGS__)
#define FL_DOARG59(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG58(s,f,a,__VA_ARGS__)
#define FL_DOARG60(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG59(s,f,a,__VA_ARGS__)
#define FL_DOARG61(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG60(s,f,a,__VA_ARGS__)
#define FL_DOARG62(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG61(s,f,a,__VA_ARGS__)
#define FL_DOARG63(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG62(s,f,a,__VA_ARGS__)
#define FL_DOARG64(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG63(s,f,a,__VA_ARGS__)

#define FL_FOREACH_(sepatator,fun,funarg,...) \
		FL_CONCAT(FL_DOARG,FL_ARG_COUNT(__VA_ARGS__))(sepatator,fun,funarg,__VA_ARGS__)
#define FL_FOREACH(sepatator,fun,funarg,...) \
		FL_FOREACH_(sepatator,fun,funarg,__VA_ARGS__)
// 为动态参数 __VA_ARGS__ 每一个参数调用 fun 宏,最大支持64个参数
// sepatator 分隔符
// fun 函数宏
// funarg 函数宏的参数

有了FL_FOREACH,就可以实现前述的需求了:

#define enum_elem(p,n) p##n,

// 定义一个名为clsName的枚举类型,动态参数提供枚举类型的元素,最多支持64个元素
// clsName##_为元素名前缀
#define FL_DEF_ENUM(clsName,...)\
enum _##clsName{\
FL_FOREACH(,enum_elem,clsName##_,__VA_ARGS__)\
	/* must be last position,for competing enum's number  */\
	clsName##_LAST_ID \
}clsName;

调用示例:

// 定义4个元素
FL_DEF_ENUM(FL_TEST0, 0, 1, 2, 4)

宏展开代码 (eclipse视图):
这里写图片描述

// 定义10个元素
FL_DEF_ENUM(FL_TEST, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

// 最大64个
FL_DEF_ENUM(FL_TEST2,\
		 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\
		10,11,12,13,14,15,16,17,18,19,\
		20,21,22,23,24,25,26,27,28,29,\
		30,31,32,33,34,35,36,37,38,39,\
		40,41,42,43,44,45,46,47,48,49,\
		50,51,52,53,54,55,56,57,58,59,\
		60,61,62,63\
		)

FL_TEST类型(eclipse视图)
这里写图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值