干:C++11 枚举类与 C 枚举

问题描述 投票:0回答:1

我有这样的课:

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...

    // spill the enum:
    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 静态成员的想法是避免重复输入,例如

if (insert() == InsertResult::INSERTED){
//  OK...
}

if (insert() == InsertResult::Status::INSERTED){
//  OK...
}

有什么简单的方法可以让它“更好”而不使用

C enum

c++ c++17 dry
1个回答
0
投票

在 C++20 中你会这样做

using enum Status;

C++20 之前,我最好的想法是编写一个宏来为您生成 constexpr 变量。下面的示例

macro_sequence_for
,是我为简化预处理器循环而制作的一个小库。

在 gcc.godbolt.org 上运行

#include <macro_sequence_for.h>

#define MAKE_ENUM(name_, members_) \
    enum class name_ {SF_FOR_EACH(BODY_ENUM_ELEM, SF_NULL, SF_NULL,, members_)};\
    SF_FOR_EACH(BODY_VAR, SF_STATE, SF_NULL, name_, members_)

#define BODY_ENUM_ELEM(n, d, x) x,
#define BODY_VAR(n, d, x) [[maybe_unused]] static constexpr d x = d::x;

然后这个:

MAKE_ENUM( E,
    (e1)
    (e2)
    (e3)
)

扩展到此:

enum class E
{
    e1,
    e2,
    e3,
};

[[maybe_unused]] static constexpr E e1 = E::e1;
[[maybe_unused]] static constexpr E e2 = E::e2;
[[maybe_unused]] static constexpr E e3 = E::e3;

这是一个更长的版本,可让您指定枚举常量值:

#include <macro_sequence_for.h>

#define MAKE_ENUM(name_, members_) \
    enum class name_ {SF_FOR_EACH(BODY_ENUM_ELEM, SF_NULL, SF_NULL,, members_)};\
    SF_FOR_EACH(BODY_VAR, SF_STATE, SF_NULL, name_, members_)

#define BODY_ENUM_ELEM(n, d, ...) BODY_ENUM_ELEM_SELECT(__VA_ARGS__, BODY_ENUM_ELEM_A, BODY_ENUM_ELEM_B,)(__VA_ARGS__)
#define BODY_ENUM_ELEM_SELECT(x, y, z, ...) z
#define BODY_ENUM_ELEM_A(name_, init_) name_ = init_,
#define BODY_ENUM_ELEM_B(name_) name_,

#define BODY_VAR(n, d, ...) BODY_VAR_(n, d, __VA_ARGS__,)
#define BODY_VAR_(n, d, x, ...) [[maybe_unused]] static constexpr d x = d::x;

MAKE_ENUM( E,
    (e1)
    (e2, 42)
    (e3)
)
© www.soinside.com 2019 - 2024. All rights reserved.