c/c++:基于for each pair 遍历 __VA_ARGS__ 中的元素,实现定义struct的宏

在上一篇博客《c/c++:for each遍历 __VA_ARGS__ 中的每一个元素》,我们具备了遍历__VA_ARGS__中元素的能力,那么具备这个能力有啥用呢? 在上篇博客中的例子中,可以利用这个遍历功能定义枚举(enum)类型。
进一步延伸思考,还可以利用这个能力定义结构体(struct)呀。当然定义结构体与枚举类似是有区别的,结构体的每个成员不光需要成员名还需要指定数据类型。所以不能简单的使用上篇文章中的FL_FOREACH宏来实现。我们需要能遍历成对参数的能力,这就是下面的宏FL_VA_FOREACH_PAIR,这个函数宏对__VA_ARGS__(必须是偶数个)中的参数以两个一组为单位进行遍历。

#define FL_DOPAIR0(s,f,a,O)
#define FL_DOPAIR2(s,f,a,t,v) f(a,t,v)
#define FL_DOPAIR4(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR2(s,f,a,__VA_ARGS__)
#define FL_DOPAIR6(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR4(s,f,a,__VA_ARGS__)
#define FL_DOPAIR8(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR6(s,f,a,__VA_ARGS__)
#define FL_DOPAIR10(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR8(s,f,a,__VA_ARGS__)
#define FL_DOPAIR12(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR10(s,f,a,__VA_ARGS__)
#define FL_DOPAIR14(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR12(s,f,a,__VA_ARGS__)
#define FL_DOPAIR16(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR14(s,f,a,__VA_ARGS__)
#define FL_DOPAIR18(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR16(s,f,a,__VA_ARGS__)
#define FL_DOPAIR20(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR18(s,f,a,__VA_ARGS__)
#define FL_DOPAIR22(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR20(s,f,a,__VA_ARGS__)
#define FL_DOPAIR24(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR22(s,f,a,__VA_ARGS__)
#define FL_DOPAIR26(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR24(s,f,a,__VA_ARGS__)
#define FL_DOPAIR28(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR26(s,f,a,__VA_ARGS__)
#define FL_DOPAIR30(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR28(s,f,a,__VA_ARGS__)
#define FL_DOPAIR32(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR30(s,f,a,__VA_ARGS__)
#define FL_DOPAIR34(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR32(s,f,a,__VA_ARGS__)
#define FL_DOPAIR36(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR34(s,f,a,__VA_ARGS__)
#define FL_DOPAIR38(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR36(s,f,a,__VA_ARGS__)
#define FL_DOPAIR40(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR38(s,f,a,__VA_ARGS__)
#define FL_DOPAIR42(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR40(s,f,a,__VA_ARGS__)
#define FL_DOPAIR44(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR42(s,f,a,__VA_ARGS__)
#define FL_DOPAIR46(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR44(s,f,a,__VA_ARGS__)
#define FL_DOPAIR48(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR46(s,f,a,__VA_ARGS__)
#define FL_DOPAIR50(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR48(s,f,a,__VA_ARGS__)
#define FL_DOPAIR52(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR50(s,f,a,__VA_ARGS__)
#define FL_DOPAIR54(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR52(s,f,a,__VA_ARGS__)
#define FL_DOPAIR56(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR54(s,f,a,__VA_ARGS__)
#define FL_DOPAIR58(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR56(s,f,a,__VA_ARGS__)
#define FL_DOPAIR60(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR58(s,f,a,__VA_ARGS__)
#define FL_DOPAIR62(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR60(s,f,a,__VA_ARGS__)
#define FL_DOPAIR64(s,f,a,t,v,...) FL_DOPAIR2(s,f,a,t,v) s FL_DOPAIR62(s,f,a,__VA_ARGS__)

// 为动态参数 __VA_ARGS__ 每两个值(一对值)执行 调用 fun 宏,最大支持64个参数,参数个数必须是偶数
// sepatator 分隔符
// fun 函数宏
// funarg 函数宏的附加参数
#define FL_VA_FOREACH_PAIR_(sepatator,fun,funarg,...) \
		FL_CONCAT(FL_DOPAIR,FL_ARG_COUNT(__VA_ARGS__))(sepatator,fun,funarg,__VA_ARGS__)
#define FL_VA_FOREACH_PAIR(sepatator,fun,funarg,...) \
		FL_VA_FOREACH_PAIR_(sepatator,fun,funarg,__VA_ARGS__)

利用上面的FL_VA_FOREACH_PAIR我们可以创建一个定义struct的宏FL_DEF_STRUCT


#define fl_def_struct_field_def(t,v) t v
#define fl_def_struct_field(a,t,v) fl_def_struct_field_def(t,v);

// 定义一个名为clsName的结构,动态参数提成员的类型和名字,最多支持32个成员
// clsName##_为元素名前缀
// 对__VA_ARGS__参数成对遍历,对每一对参数执行fl_def_struct_field函数
// fl_def_struct_field函数用于定义每一个成员变量。
#define FL_DEF_STRUCT(clsName, ...)\
typedef struct _##clsName {\
	FL_VA_FOREACH_PAIR(,fl_def_struct_field, , __VA_ARGS__)\
}clsName,* clsName##_ptr;

调用示例:

// 定义具有三个成员变量的Struct
FL_DEF_STRUCT(test_struct10,char, m1,long, m2,char*, m3)

展开代码(eclipse显示编译器花了18步完成宏展开,so艰难):
这里写图片描述

这里写图片描述

发挥你的想象力,你会发现你可以顺着这个思路用macro干很多事儿。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

10km

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

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

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

打赏作者

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

抵扣说明:

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

余额充值