如何在C++中动态选取两个相似结构体的成员且避免代码重复?
前置说明
原类定义中test为私有成员,以下方案默认你已有该成员的合法访问权限(如友元声明、实际场景中类为struct结构等),否则会触发编译权限错误,且所有方案均不会修改原有两个类的内存布局。
方案1:运行时分派表(推荐,适合大量重复逻辑场景)
将x取值和对应类型操作提前注册为全局映射表,后续所有同类操作无需重复写if分支,新增类型时只需修改映射表即可:
#include <functional> #include <unordered_map> // 全局操作映射,可单独放到工具头文件中 std::unordered_map<int, std::function<void(void*, int)>> g_test_setter = { {1, [](void* obj, int val) { reinterpret_cast<XY*>(obj)->test = val; }}, {2, [](void* obj, int val) { reinterpret_cast<XYZ*>(obj)->test = val; }} }; // 业务代码使用示例 void Function(void* object, int x) { // 一行完成赋值,无需写判断 g_test_setter[x](object, 1); }
如果需要读取test的值,也可以对应新增读操作的映射表,逻辑完全一致。
方案2:通用模板分派(高灵活性,适合多操作场景)
如果有大量不同的成员操作需求,不想为每个成员单独维护映射表,可以写通用模板分派函数,支持传入任意自定义操作:
#include <cstdlib> template<typename Callable> decltype(auto) type_dispatch(int x, void* obj, Callable&& op) { switch(x) { case 1: return op(reinterpret_cast<XY*>(obj)); case 2: return op(reinterpret_cast<XYZ*>(obj)); default: abort(); // 调试阶段可加断言校验非法x取值 } } // 业务代码使用示例 void Function(void* object, int x) { type_dispatch(x, object, [](auto* typed_ptr) { // 此处可写任意针对XY、XYZ都有效的操作,自动适配类型 typed_ptr->test = 1; // 例如可以加读取逻辑:int cur_val = typed_ptr->test; }); }
该方案只需定义一次分派函数,即可适配所有针对两个类的通用成员操作,无需额外维护其他代码。
方案3:宏封装(最小改动,适合快速替换旧代码)
如果不想调整现有代码结构,只是需要简化重复的if分支写法,可以用宏做轻量封装:
// 仅针对test赋值的简化宏 #define SET_TEST(obj, type_id, val) \ do { \ if ((type_id) == 1) reinterpret_cast<XY*>(obj)->test = (val); \ else if ((type_id) == 2) reinterpret_cast<XYZ*>(obj)->test = (val); \ } while(0) // 业务代码使用示例 void Function(void* object, int x) { SET_TEST(object, x, 1); }
如果需要支持任意操作,可以用更通用的宏:
// 通用指针分派宏 #define DISPATCH_TYPE(type_id, obj, ptr_name, code) \ do { \ if ((type_id) == 1) { \ auto* ptr_name = reinterpret_cast<XY*>(obj); \ code \ } else if ((type_id) == 2) { \ auto* ptr_name = reinterpret_cast<XYZ*>(obj); \ code \ } \ } while(0) // 使用示例 void Function(void* object, int x) { DISPATCH_TYPE(x, object, ptr, { ptr->test = 1; // 其他自定义操作 }); }
注意:所有方案均基于
object指针实际类型与x取值严格对应的前提,错误匹配会触发未定义行为,建议调试版本增加取值合法性校验。
内容的提问来源于stack exchange,提问作者iFarbod
相关产品推荐
相关产品推荐

