这是以下 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 语言。所以您也许可以用模板做一些花哨的事情。
根据下面 Thomas Matthews 的回答,我得出以下结论:
这不是完全自动的,但使用起来并不太困难。 在重新定义 NODE_GRAPH_TYPE 时,我可以逐字复制 SDK header 中的表并将其放入 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";
}
最佳答案
您不能将 enum
转换为文本或将文本转换为 enum
自动,仅作为 enum
标识符在编译期间存在,而不是在运行时存在。
最好的方法是表查找或 std::map
。
我使用表查找,因为我可以使表static
和const
并在main
之前对其进行初始化。
struct Enum_Entry
{
int enum_value;
const char * enum_text;
};
static const Enum_Entry enum_table[] =
{
{GT_UNKNOWN, "GT_UNKNOWN"},
//...
};
static const unsigned int table_capacity =
sizeof(enum_table) / sizeof(enum_table[0]);
通过将 enum
值和文本放在同一个表中,一个表可用于将文本转换为 enum
和 enum
到文本。
使用 std::map
时,其中一个转换方向效率不高。
关于c++ - 如何自动将枚举转换为字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42123397/