在编译时检查多个枚举是否具有唯一值

时间:2018-08-27 06:15:29

标签: c++ c++11 enums compile-time

我想使用多个枚举列出错误代码,以便可以在不同文件中定义这些枚举。如何在编译时检查这些枚举中的所有值是否唯一?

我目前正在定义这样的枚举:

constexpr int ERROR_CODE_MAX = 1000000;

#define ERRORS1_LIST(f) \
    f(IRRADIANCE_MUST_BE_BETWEEN, 103, L"message1") \
    f(MODULE_MUST_BE_SELECTED, 104, L"message2")

#define GENERATE_ENUM(key, value, name) key = value,
#define GENERATE_LIST(key, value, name) { key, name },

enum Errors1 {
    ERRORS1_LIST(GENERATE_ENUM)
    UndefinedError1 = ERROR_CODE_MAX - 1
};

// Error code 103 is defined twice; should trigger compile error
#define ERRORS2_LIST(f) \
    f(OPERATOR_MUST_BE_SELECTED, 105, L"message3")  \
    f(IRRADIANCE_MUST_BE_BETWEEN2, 103, L"message4")

enum Errors2 {
    ERRORS2_LIST(GENERATE_ENUM)
    UndefinedError2 = ERROR_CODE_MAX - 2
};

// List of all error messages
// I want to check error code uniqueness in the same place where I define this
static const std::map<int, std::wstring> ErrorMessageList = {
    ERRORS1_LIST(GENERATE_LIST)
    ERRORS2_LIST(GENERATE_LIST)
    {UndefinedError1, L"Undefined"}
};

2 个答案:

答案 0 :(得分:1)

一种方法是使用变量名称中的每个错误代码创建变量:

#define GENERATE_COUNTER(key, value, name) constexpr int IsErrorcodeUnique ## value = 1;

namespace {

ERRORS1_LIST(GENERATE_COUNTER)
ERRORS2_LIST(GENERATE_COUNTER)

} // namespace

答案 1 :(得分:1)

您不能这样做。编译器不会限制您可以分配给枚举的值。但是您可以让编译器使用switch来检查enum(s)的重复值,如下所示:

    enum ERROR_LIST1
{
    ERROR1 = 1,
    IRRADIANCE_MUST_BE_BETWEEN = 103,
};


enum ERROR_LIST2
{
    ERROR3 = 2,
    IRRADIANCE_MUST_BE_BETWEEN2 = 103,
};


void TestDublicateEnumValue() 
{
    int x = 0;
    switch (x)
    {
    case ERROR1 :
    case IRRADIANCE_MUST_BE_BETWEEN:
    case ERROR3 :
    case IRRADIANCE_MUST_BE_BETWEEN2://this will generate compiler error
        break;
    }   
}