如何通过C++宏实现输入枚举值返回关联的枚举类型?
可行性结论
你的需求完全可以实现,当前的实现思路是正确的,仅需要修正几个细节问题即可正常使用。
现有实现的问题修正
ENUM_TYPE宏末尾多余分号:你当前定义的#define ENUM_TYPE(T) Assoc<T>::type;最后带了分号,直接放到模板参数里会触发语法错误,必须删掉末尾的分号。- 共用Assoc结构体不会冲突:
Assoc是依赖模板参数类型的,不同枚举类型的枚举值作为模板参数时,属于不同的模板实例,不会出现名称冲突。单组映射场景下完全不需要额外修改,如果你确实需要同时支持多组独立的关联映射,可以再加别名参数区分。 - 声明顺序注意:
ENUM_ASSOCIATION用到的枚举值和目标类型必须先完成声明/前置声明,比如作为键的Sorting枚举、作为值的Color枚举都要先声明,再写绑定关系。
修正后的完整可运行实现
// 声明关联映射的主模板,EnumType是枚举值所属的枚举类型,比如Sorting #define DECLARE_ENUM_ASSOCIATION(EnumType) template<EnumType> struct Assoc; // 绑定枚举值和对应类型,EnumVal是枚举值,TargetType是要关联的目标类型 #define ENUM_ASSOCIATION(EnumVal, TargetType) \ template<> \ struct Assoc<EnumVal> { \ using type = TargetType; \ }; // 获取枚举值关联的类型,已移除末尾多余分号 #define ENUM_TYPE(EnumVal) Assoc<EnumVal>::type
使用示例:
// 先声明要关联的目标类型 enum Color { RED, BLUE }; enum Price { LOW, MID, HIGH }; // 定义作为键的枚举 enum Sorting { COLOR, PRICE }; // 声明关联映射的主模板 DECLARE_ENUM_ASSOCIATION(Sorting) // 绑定枚举值和对应类型 ENUM_ASSOCIATION(COLOR, Color) ENUM_ASSOCIATION(PRICE, Price) // 测试函数模板 template<typename T> void DoSomething() { // 可正常使用关联后的T类型 } void someFunc() { // 等价于DoSomething<Color>(); DoSomething<ENUM_TYPE(COLOR)>(); // 等价于DoSomething<Price>(); DoSomething<ENUM_TYPE(PRICE)>(); }
上述实现兼容C++11及所有后续标准,无第三方依赖。
可选优化:支持多组独立关联映射
如果需要同时存在多组互不干扰的关联映射,可以给映射结构体加自定义名称,修改后的宏如下:
#define DECLARE_ENUM_ASSOCIATION(MapName, EnumType) template<EnumType> struct MapName; #define ENUM_ASSOCIATION(MapName, EnumVal, TargetType) \ template<> \ struct MapName<EnumVal> { \ using type = TargetType; \ }; #define ENUM_TYPE(MapName, EnumVal) MapName<EnumVal>::type
使用示例:
DECLARE_ENUM_ASSOCIATION(SortTypeMap, Sorting) ENUM_ASSOCIATION(SortTypeMap, COLOR, Color) ENUM_ASSOCIATION(SortTypeMap, PRICE, Price) // 使用时指定映射名即可 DoSomething<ENUM_TYPE(SortTypeMap, COLOR)>();
内容的提问来源于stack exchange,提问作者DemonBismuth
相关产品推荐
相关产品推荐

