如何编写GCC可变参数宏CREATE_STRUCT以生成指定成员的结构体?
实现GCC兼容的CREATE_STRUCT宏
没问题,我来帮你搞定这个需求!针对GCC,我们可以用预处理器的可变参数宏和简单的参数计数技巧来实现,完全不用复杂的黑魔法,下面是具体方案:
完整实现代码
// 辅助宏:将单个成员名转换为std::string成员声明 #define MEMBER(name) std::string name; // 针对不同数量成员的展开宏(支持1-5个成员,可按需扩展) #define FOR_EACH_1(func, a) func(a) #define FOR_EACH_2(func, a, b) func(a) func(b) #define FOR_EACH_3(func, a, b, c) func(a) func(b) func(c) #define FOR_EACH_4(func, a, b, c, d) func(a) func(b) func(c) func(d) #define FOR_EACH_5(func, a, b, c, d, e) func(a) func(b) func(c) func(d) func(e) // 提取参数数量,匹配对应的展开宏 #define GET_FOR_EACH(_1,_2,_3,_4,_5,NAME,...) NAME #define FOR_EACH(func, ...) \ GET_FOR_EACH(__VA_ARGS__, FOR_EACH_5, FOR_EACH_4, FOR_EACH_3, FOR_EACH_2, FOR_EACH_1)(func, __VA_ARGS__) // 最终的CREATE_STRUCT宏 #define CREATE_STRUCT(name, ...) \ struct name { \ FOR_EACH(MEMBER, __VA_ARGS__) \ };
怎么使用
完全按照你想要的方式调用就行:
// 生成带1个成员的结构体 CREATE_STRUCT(my_struct1, foo); // 生成带2个成员的结构体 CREATE_STRUCT(my_struct2, foo, bar); // 生成带4个成员的结构体 CREATE_STRUCT(my_struct3, id, name, email, address);
展开效果
上面的代码会被GCC预处理器展开成:
struct my_struct1 { std::string foo; }; struct my_struct2 { std::string foo; std::string bar; }; struct my_struct3 { std::string id; std::string name; std::string email; std::string address; };
原理说明
- MEMBER宏:最基础的辅助宏,负责把单个成员名转换成
std::string 成员名;的声明格式。 - FOR_EACH_N宏:针对1到5个成员分别定义展开规则,确保每个成员都被MEMBER宏处理。
- GET_FOR_EACH宏:通过可变参数的长度,自动匹配对应的FOR_EACH_N宏(比如传入4个成员就匹配FOR_EACH_4)。
- CREATE_STRUCT宏:把结构体名和成员列表传入,利用FOR_EACH完成所有成员的展开,最终生成完整的结构体定义。
扩展说明
如果以后需要支持更多成员(比如6个、7个),只需要添加对应的FOR_EACH_6、FOR_EACH_7宏,然后更新GET_FOR_EACH的参数列表即可,非常灵活。
这个方案兼容GCC 4.8及以上版本,不需要依赖C++20的新特性,适合大多数场景。
内容的提问来源于stack exchange,提问作者463035818_is_not_an_ai
相关产品推荐
相关产品推荐

