Проверьте во время компиляции, что несколько перечислений имеют уникальные значения
Я хочу перечислить коды ошибок, используя несколько перечислений, чтобы я мог определить эти перечисления в разных файлах. Как проверить во время компиляции, что все значения в этих перечислениях уникальны?
В настоящее время я определяю перечисления следующим образом:
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 ответа
Ты не можешь сделать это. Компилятор не будет ограничивать значения, которые вы можете присвоить перечислениям. однако вы можете позволить компилятору проверять дубликаты значений перечислений с помощью switch следующим образом
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;
}
}
Один из способов сделать это - создать переменные, используя каждый код ошибки в имени переменной:
#define GENERATE_COUNTER(key, value, name) constexpr int IsErrorcodeUnique ## value = 1;
namespace {
ERRORS1_LIST(GENERATE_COUNTER)
ERRORS2_LIST(GENERATE_COUNTER)
} // namespace