C++仅支持引用传递的编译时自定义枚举类实现可行性咨询
结论
你的实现完全满足你提出的所有需求,设计思路是合理的。
需求匹配验证
- 禁止任意实例创建:
MyEnum的构造函数为私有属性,仅友元MyEnumValues有权限初始化实例,而MyEnumValues的构造函数已被删除、无法创建实例,外部代码完全没有办法构造出新的MyEnum对象,符合要求。 - 禁止拷贝/移动操作:你已经显式删除了拷贝构造、移动构造、拷贝赋值、移动赋值四个函数,因此
MyEnum对象无法被复制、移动,只能通过引用或指针传递,符合你的设计预期。 - 编译时实体:
MyEnum的构造函数是constexpr修饰的,MyEnumValues里的T1、T2是inline static constexpr属性,所有值都在编译期完成初始化,没有运行时初始化风险,满足编译时实体的要求。
关于你提到的Java风格静态成员的问题
你判断无法将T1、T2作为静态成员直接放在MyEnum类内部是正确的:C++中类的内部定义静态成员时,类本身还处于不完全类型状态,无法直接实例化自身类型的静态成员,你单独设计MyEnumValues作为值容器是这类自定义枚举实现的标准解决方案,没有问题。
可优化的细节点
- 你的移动构造函数声明为
MyEnum(const MyEnum&&) = delete;,加const修饰右值引用不符合常规移动语义写法,不过你已经删除了该函数,不影响功能,建议修改为MyEnum(MyEnum&&) = delete;更规范。 - 代码中使用了
"t1"sv的字符串视图字面量,需要显式包含<string_view>头文件,当前代码依赖部分编译器的间接包含才能编译,不符合C++标准要求。 - 如果使用C++20及以上标准,可以给
MyEnum添加默认的三路比较运算符constexpr auto operator<=>(const MyEnum&) const = default;,可以一次性获得所有比较运算符的实现,不需要单独写==、!=。
内容的提问来源于stack exchange,提问作者VladG
相关产品推荐
相关产品推荐

