You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 16:42:23