У меня есть какой-то устаревший код, написанный на языке C, и я хотел бы провести рефакторинг на C ++ 14. Я должен столкнуться с проблемой, которую не могу решить.
В старом простом C был способ переключения между массивами.
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
const int sz = (machine == 1) ? NELEMS (errors1) : NELEMS (errors2);
const struct Error *error = (machine == 1) ? &errors1[0] : &errors2[0];
Код выше работает, нокак-то не читается. Я хотел бы использовать std::array
, потому что им легко манипулировать с меньшим количеством читаемого кода. std::vector
использует память кучи, и я хотел бы, чтобы результат был ПЗУ.
Тернарный оператор кода C ++ const Error &error = (machine == 1) ? errors1 : errors2;
его нельзя использовать таким образом, поскольку std::array<Error, 3> errors1
и std::array<Error, 5> errors2
разные типы! так как же можно достичь той же функциональности с std::array
?
Legacy C code
enum ErrorCode {
ERR_NOT_FOUND,
ERR_FORBIDDEN,
ERR_INTERNAL,
ERR_UNAVAILABLE,
ERR_NO_RESPONSE,
ERR_UNSUPPORTED,
ERR_OUT_OF_MEMORY,
ERR_TIMEOUT
};
struct Error {
int id;
int code;
const char *str;
};
static const struct Error errors1[] = {
{1001, ERR_NOT_FOUND, "Not Found"},
{1002, ERR_FORBIDDEN, "Forbidden"},
{1003, ERR_INTERNAL, "Internal Error"}
};
static const struct Error errors2[] = {
{1004, ERR_UNAVAILABLE, "Temporarly Unavailable"},
{1005, ERR_NO_RESPONSE, "No Response"},
{1006, ERR_UNSUPPORTED, "Unsupported"},
{1007, ERR_OUT_OF_MEMORY, "Insufficient Memory"},
{1008, ERR_TIMEOUT, "Timeout"}
};
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
char *error_to_string (char machine, int id) {
const int sz = (machine == 1) ? NELEMS (errors1) : NELEMS (errors2);
const struct Error *error = (machine == 1) ? &errors1[0] : &errors2[0];
const char *str = "Unknown";
for (int i = 0; i < sz; i++) {
if (error[i].id == id) {
str = error[i].str;
break;
}
}
return str;
}
попытка получить модеренный код C ++ с той же функциональностью, что и в C code
std::array<Error, 3> errors1= {{
{1001, ERR_NOT_FOUND, "Not Found"},
{1002, ERR_FORBIDDEN, "Forbidden"},
{1003, ERR_INTERNAL, "Internal Error"}
}};
std::array<Error, 5> errors2= {{
{1004, ERR_UNAVAILABLE, "Temporarly Unavailable"},
{1005, ERR_NO_RESPONSE, "No Response"},
{1006, ERR_UNSUPPORTED, "Unsupported"},
{1007, ERR_OUT_OF_MEMORY, "Insufficient Memory"},
{1008, ERR_TIMEOUT, "Timeout"}
}};
const char *error_to_string (char machine, int id) {
const char *str = (char*) "Unknown";
const auto errors = (machine == 1) ? &errors1[0] : &errors2[0];
for (auto error : errors) {
if (error.id == id) {
str = error.str;
break;
}
}
return str;
}