C++11 enum class替代C enum:优化代码避免重复书写方案问询
优化结构体嵌套枚举类的访问方式
我定义了如下结构体InsertResult,其中包含一个嵌套的枚举类Status:
struct InsertResult{ enum class Status{ INSERTED , UPDATED_IN_PLACE , REPLACED , SKIP_INSERTED , ERROR_NO_MEMORY , ERROR_INVALID , ERROR }; bool ok; Status status; // more members here... // 手动暴露枚举成员,简化访问 constexpr static auto INSERTED = Status::INSERTED ; constexpr static auto UPDATED_IN_PLACE = Status::UPDATED_IN_PLACE ; constexpr static auto REPLACED = Status::REPLACED ; constexpr static auto SKIP_INSERTED = Status::SKIP_INSERTED ; constexpr static auto ERROR_NO_MEMORY = Status::ERROR_NO_MEMORY ; constexpr static auto ERROR_INVALID = Status::ERROR_INVALID ; constexpr static auto ERROR = Status::ERROR ; };
现在通过声明这些constexpr静态成员,我可以直接用InsertResult::INSERTED来访问枚举值,而不用写冗长的InsertResult::Status::INSERTED。但这种手动逐个声明的方式比较繁琐,想知道在不使用C风格枚举的前提下,有没有更简便的优化方式?
方案1:C++20 用using enum一键导入(最优解)
C++20引入了using enum声明,可以直接将枚举类的所有成员导入到当前作用域中,无需手动逐个声明静态成员:
struct InsertResult{ enum class Status{ INSERTED , UPDATED_IN_PLACE , REPLACED , SKIP_INSERTED , ERROR_NO_MEMORY , ERROR_INVALID , ERROR }; using enum Status; // 一行代码导入所有枚举成员到结构体作用域 bool ok; Status status; // more members here... };
使用方式和之前完全一致:
if (insert() == InsertResult::INSERTED){ // 处理逻辑... }
方案2:C++17 简化静态成员声明
如果项目还在使用C17(不支持using enum),可以利用C17中constexpr静态成员默认inline的特性,省略static关键字,稍微简化代码:
struct InsertResult{ enum class Status{ INSERTED , UPDATED_IN_PLACE , REPLACED , SKIP_INSERTED , ERROR_NO_MEMORY , ERROR_INVALID , ERROR }; bool ok; Status status; // more members here... // C++17起constexpr静态成员默认inline,可省略static constexpr auto INSERTED = Status::INSERTED; constexpr auto UPDATED_IN_PLACE = Status::UPDATED_IN_PLACE; constexpr auto REPLACED = Status::REPLACED; constexpr auto SKIP_INSERTED = Status::SKIP_INSERTED; constexpr auto ERROR_NO_MEMORY = Status::ERROR_NO_MEMORY; constexpr auto ERROR_INVALID = Status::ERROR_INVALID; constexpr auto ERROR = Status::ERROR; };
不推荐的方案:宏定义
虽然可以用宏来自动生成静态成员,但宏会污染全局作用域,且不利于代码可读性和调试,因此不建议使用:
#define EXPOSE_ENUM_VAL(ENUM_TYPE, VAL) constexpr static auto VAL = ENUM_TYPE::VAL; struct InsertResult{ enum class Status{ INSERTED , UPDATED_IN_PLACE , REPLACED , SKIP_INSERTED , ERROR_NO_MEMORY , ERROR_INVALID , ERROR }; bool ok; Status status; // more members here... EXPOSE_ENUM_VAL(Status, INSERTED) EXPOSE_ENUM_VAL(Status, UPDATED_IN_PLACE) EXPOSE_ENUM_VAL(Status, REPLACED) EXPOSE_ENUM_VAL(Status, SKIP_INSERTED) EXPOSE_ENUM_VAL(Status, ERROR_NO_MEMORY) EXPOSE_ENUM_VAL(Status, ERROR_INVALID) EXPOSE_ENUM_VAL(Status, ERROR) }; #undef EXPOSE_ENUM_VAL
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

