Это расширение следующего question которое уже имеет отличные ответы.Как я могу преобразовать перечисление в строку автоматически
Однако во всех ответах, где расширение выполняется предварительным процессором, перечисления объявляются особым образом в рамках того же проекта. Но что, если заголовочный файл, объявляющий эти перечисления, не является вашим собственным, или перечисления объявлены вне порядка id.
В моем случае, у меня есть SDK, который я использую, где большие таблицы перечислений уже объявлены в отдельном файле заголовка, как следующее:
#define NODE_GRAPH_TYPE(_name, _enum) _name = _enum,
enum NodeGraphType
{
// next available ID value is 7
NODE_GRAPH_TYPE(GT_UNKNOWN , 0)
NODE_GRAPH_TYPE(GT_STANDARD , 1)
NODE_GRAPH_TYPE(GT_APP_SETTINGS , 3)
NODE_GRAPH_TYPE(GT_GEOMETRYARCHIVE , 2)
NODE_GRAPH_TYPE(GT_SCRIPTED , 5)
NODE_GRAPH_TYPE(GT_SCRIPT_STORAGE , 6)
NODE_GRAPH_TYPE(GT_PROJECT_SETTINGS , 4)
};
То, что я хочу сделать, это попытаться Во избежание такого типа вещи:
function NODE_GRAPH_NAME(int type)
{
switch(type)
{
case: GT_PROJECT_SETTINGS:
return "GT_PROJECT_SETTINGS";
// ...
};
}
или
static const char* NODE_GRAPH_NAME[] = {
"GT_UNKNOWN",
/// ...
}
лучшим, что я пришел с этим т его до сих пор:
#define STRINGIFY(_x) #_x
static const char* NODE_GRAPH_NAME[] = {
STRINGIFY(GT_UNKNOWN),
STRINGIFY(GT_STANDARD),
STRINGIFY(GT_GEOMETRYARCHIVE),
STRINGIFY(GT_APP_SETTINGS)
// etc
};
Но она по-прежнему требует от меня, чтобы дублировать все таблицы перечислений и не только это, но они в порядке и двойной проверки нет никаких отверстий.
Возможно ли более элегантный и автоматический способ решения этой проблемы? Если это помогает, я на самом деле компилирую это под C++. Но библиотека, к которой я привязываюсь, является чистым C. Поэтому вы могли бы что-то придумать с шаблонами.
Основываясь на Томаса Matthews ответ ниже, это то, что я придумал следующее:
, который не полностью автоматизирована, но не слишком трудно работать. При переопределении NODE_GRAPH_TYPE я могу скопировать стенограмму таблицы из заголовка SDK и поместить ее в определение таблицы NODE_GRAPH_TYPES. И это работает. Затем я могу создать функцию поиска, чтобы найти требуемый элемент. Самое приятное в этом - это то, что дыры не имеют значения, и не выходят из строя.
#undef NODE_GRAPH_TYPE
#define NODE_GRAPH_TYPE(_name, _enum) { _enum, #_name },
static const Enum_Entry NODE_GRAPH_TYPES[] =
{
NODE_GRAPH_TYPE(GT_UNKNOWN , 0)
NODE_GRAPH_TYPE(GT_STANDARD , 1)
NODE_GRAPH_TYPE(GT_APP_SETTINGS , 3)
NODE_GRAPH_TYPE(GT_GEOMETRYARCHIVE , 2)
NODE_GRAPH_TYPE(GT_SCRIPTED , 5)
NODE_GRAPH_TYPE(GT_SCRIPT_STORAGE , 6)
NODE_GRAPH_TYPE(GT_PROJECT_SETTINGS , 4)
};
static const unsigned int NODE_GRAPH_TYPES_COUNT =
sizeof(NODE_GRAPH_TYPES)/sizeof(NODE_GRAPH_TYPES[0]);
const char* NODE_GRAPH_TYPE_NAME(int id)
{
for (int i = 0; i < NODE_GRAPH_TYPES_COUNT; ++i){
if (PIN_TYPES[i].enum_value == id)
return PIN_TYPES[i].enum_text;
}
return "Unknown";
}
Эй, это замечательно. Я придумал что-то, основанное на этой идее. – Matt