我有这样的课:
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++20 中你会这样做
using enum Status;
。
C++20 之前,我最好的想法是编写一个宏来为您生成 constexpr 变量。下面的示例
macro_sequence_for
,是我为简化预处理器循环而制作的一个小库。
#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)
)