C++中如何实现遍历类成员生成代码的宏且无需将成员存入数组?
无需vector存储成员,实现自动遍历类成员调用CVAR_WRITE的宏方案
你的需求是让SAVE_CVARS宏自动遍历CCvars的所有成员并调用CVAR_WRITE,等价于手动逐个调用的效果,同时不想用vector存储成员。这里最靠谱的方案是用X宏(X-Macro)——这是C++预处理阶段常用的技巧,能让你复用同一个成员列表来生成类定义和遍历代码,完全不需要额外的运行时存储。
具体实现步骤
1. 定义成员列表的X宏
首先把CCvars的所有成员整理成一个宏列表,每个成员包含名称和类型:
// 可以放在头文件的合适位置,比如CCvars类定义之前 #define CCVARS_MEMBERS(X) \ X(gui, bool) \ X(size, int) \ X(precision, float)
2. 用X宏生成CCvars类
原来的类定义可以改成用这个宏来自动生成成员,避免手动写重复代码:
// .h文件 class CCvars { public: // 用X宏生成类成员定义 #define DEFINE_MEMBER(name, type) type name; CCVARS_MEMBERS(DEFINE_MEMBER) #undef DEFINE_MEMBER }; extern CCvars g_Cvars;
3. 实现CVAR_WRITE和SAVE_CVARS宏
现在可以基于同一个成员列表,让SAVE_CVARS自动展开成对每个成员的CVAR_WRITE调用:
// 你的CVAR_WRITE宏(这里保留你原来的框架,补充实际逻辑) #define CVAR_WRITE(cv) \ std::string str(#cv); \ // 这里添加你的保存逻辑,比如写入配置文件、序列化等操作 // SAVE_CVARS宏:遍历成员列表,逐个调用CVAR_WRITE #define SAVE_CVARS(cvarObject) \ #define CALL_CVAR_WRITE(name, type) CVAR_WRITE(cvarObject.name); \ CCVARS_MEMBERS(CALL_CVAR_WRITE) \ #undef CALL_CVAR_WRITE
4. 主函数中的用法
和你期望的完全一样,只需一行代码:
void SaveCvars() { CCvars g_Cvars; SAVE_CVARS(g_Cvars); }
预处理后的效果
当编译器预处理这段代码时,SAVE_CVARS(g_Cvars)会被展开成:
CVAR_WRITE(g_Cvars.gui); CVAR_WRITE(g_Cvars.size); CVAR_WRITE(g_Cvars.precision);
完全等价于你手动写的版本,而且没有任何vector之类的额外存储。
方案优势
- 完全在预处理阶段完成,运行时没有额外开销;
- 成员列表只需要维护一次,类定义和遍历逻辑自动同步,避免了手动修改时的遗漏或不一致;
- 不需要依赖任何第三方库或C的高级特性(比如C20的反射,而且即使是C++20反射也没法直接在宏里用)。
内容的提问来源于stack exchange,提问作者computersaretrash
相关产品推荐
相关产品推荐

