能否为枚举的包装类实现类型特征,通过内部枚举类型获取对应包装类?
能否为枚举的包装类实现类型特征,通过内部枚举类型获取对应包装类?
嘿,这个需求完全可以实现!我之前在项目里也碰到过类似的场景——需要从嵌套在包装类里的枚举类型,反向拿到它的外层包装类,用来复用包装类里的工具方法(比如你提到的toString())。下面就给你一步步拆解实现方式:
一、定义基础的类型特征模板
首先,我们需要一个基础的模板,用来“存储”枚举类型到包装类的映射关系,同时给没有映射的情况加上编译时错误提示:
#include <type_traits> // 基础类型特征模板,默认情况下没有对应包装类 template <typename EnumType> struct enum_wrapper_trait { // 如果传入的枚举没有对应的包装类,编译时会触发这个断言 static_assert(!std::is_enum_v<EnumType>, "该枚举类型没有对应的包装类,请先定义映射关系!"); using type = void; }; // 方便使用的别名模板,简化类型获取 template <typename EnumType> using get_enum_wrapper_t = typename enum_wrapper_trait<EnumType>::type;
二、为包装类的内部枚举建立映射
接下来,针对每个你的包装类(比如MyEnum、MyEnum2),我们需要显式特化上面的模板,把内部枚举和外层包装类关联起来。
比如你的MyEnum定义:
struct MyEnum { enum __Enum { A, B }; // 你提到的成员方法 static const char* toString(__Enum val) { switch(val) { case A: return "A"; case B: return "B"; default: return "Unknown"; } } }; // 特化模板,将MyEnum::__Enum映射到MyEnum template <> struct enum_wrapper_trait<MyEnum::__Enum> { using type = MyEnum; };
同样的,其他包装类也可以照这个方式处理:
struct MyEnum2 { enum __Enum { X, Y, Z }; static const char* toString(__Enum val) { switch(val) { case X: return "X"; case Y: return "Y"; case Z: return "Z"; default: return "Unknown"; } } }; template <> struct enum_wrapper_trait<MyEnum2::__Enum> { using type = MyEnum2; };
三、简化大量包装类的映射工作
如果你的项目里有很多这样的包装类,每次手动写特化代码会很繁琐。这时候可以用宏来简化重复代码:
// 定义一个宏,自动生成枚举到包装类的映射特化 #define DEFINE_ENUM_WRAPPER_MAPPING(WrapperClass) \ template <> \ struct enum_wrapper_trait<typename WrapperClass::__Enum> { \ using type = WrapperClass; \ }
之后,每个包装类定义完之后,只需要加一行宏调用就行:
struct YourEnum { enum __Enum { Foo, Bar }; static const char* toString(__Enum val) { /* 实现逻辑 */ } }; DEFINE_ENUM_WRAPPER_MAPPING(YourEnum); struct HisEnum { enum __Enum { Baz, Qux }; static const char* toString(__Enum val) { /* 实现逻辑 */ } }; DEFINE_ENUM_WRAPPER_MAPPING(HisEnum);
四、测试使用
现在你就可以通过内部枚举类型,轻松拿到对应的包装类了:
int main() { // 编译时验证映射是否正确 static_assert(std::is_same_v<get_enum_wrapper_t<MyEnum::__Enum>, MyEnum>, "MyEnum的映射关系错误!"); static_assert(std::is_same_v<get_enum_wrapper_t<MyEnum2::__Enum>, MyEnum2>, "MyEnum2的映射关系错误!"); // 实际使用:通过枚举类型获取包装类,调用其方法 using Wrapper = get_enum_wrapper_t<MyEnum::__Enum>; std::cout << Wrapper::toString(MyEnum::A) << std::endl; // 输出 "A" return 0; }
这样就完全满足你的需求了——不管有多少个包装类,只要建立好映射,就能通过get_enum_wrapper_t<EnumType>直接拿到对应的外层包装类。
内容来源于stack exchange
相关产品推荐
相关产品推荐

