我想将char *
转换为enum
,因此我使用this。但我在将char *
转换为enum
我无法更改enum
。同样type[]
是动态的,用于简化我正在显示静态值。
enum type_t {
MSG_1 = 0,
MSG_2
};
char type[] = "MSG_1|MSG_2";
char *type_char;
type_char = strtok (type,"|");
while (type_char != NULL)
{
type_t type_enum = static_cast<type_t >(type_char );
type_char = strtok (NULL, "|;");
}
我收到以下错误
error: invalid static_cast from type 'char*' to type 'type_t'
我想将char *
转换为enum
答案 0 :(得分:5)
与其他具有更强运行时“反射”功能的语言不同,在C ++中enum
是纯粹的编译时工件。编译完成后,无法获取枚举常量的名称。调试器可以通过读取编译器为调试器准备的特殊表来获取它们,但访问这些文件会适得其反。
如果您希望能够将枚举名称转换为其值,请从unordered_map
向string
创建enum
,静态填充,并根据需要执行查找:< / p>
static std::unordered_map<std::string,type_t> nameToTypeT;
...
nameToTypeT["MSG_1"] = MSG_1;
nameToTypeT["MSG_2"] = MSG_2;
...
type_t = nameToTypeT[std::string(type_char)];
答案 1 :(得分:2)
您必须编写将字符串中的文本转换为相关枚举值的代码。
我通常通过沿着以下几行编写函数来实现这一点:
type_t str_to_type_t(const char *str)
{
#define X(x) { #x, x }
struct entry
{
const char *name;
type_t value;
};
entry table[] = {
X(MSG_1),
X(MSG_2)
};
for(auto e : table)
{
if (strcmp(e.name, s) == 0)
return e.value;
}
return -1; // Or MSG_UNKNOWN or similar.
}
如果有大量枚举,那么使用std::map<std::string, type_t> table;
然后使用if ((auto it = table.find(s)) != table.end()) { return it->second;
[或unordered_map
,也许是更好的解决方案,但对于少数枚举,它几乎没有差。
答案 2 :(得分:1)
以下是一个例子:
struct entry_t
{
type_t value;
const char *literal;
};
static const entry_t table[] =
{
{MSG_1, "MSG1"},
{MSG_2, "MSG2"},
};
type_t typeFromLiteral(const char *literal)
{
for (size_t i = 0; i < sizeof(table)/sizeof(table[0]); ++i)
{
if (0 == strcmp(table[i].literal, literal))
{
return table[i].value;
}
};
abort();
}
答案 3 :(得分:0)
您无法从char *
投射到enum
,它们是不兼容的类型。你有三个选择
使用
if (strcmp(textualRepresentation, "EnumValue1") == 0)
return EnumValue1;
else if (strcmp(textualRepresentation, "EnumValue2") == 0)
return EnumValue2;
创建一个包含文本表示和enum
值的结构,然后使用bsearch()
匹配文本表示并检索enum
值。
struct EnumData {
const char *name;
Enum value;
};
EnumData enums[ENUM_COUNT] = {
{"EnumValue1", EnumValue1},
{"EnumValue2", EnumValue2}
};
int compare_enums(const void *const lhs, const void *const rhs)
{
return strcmp(reinterpret_cast<const EnumData *>(lhs)->name,
reinterpret_cast<const EnumData *>(rhs)->name);
}
然后像这样搜索
EnumData key;
void *found;
key.name = "EnumValue2";
found = bsearch(&key, enums, ENUM_COUNT, sizeof(EnumData), compare_enums);
if (found != NULL)
std::cout << reinterpret_cast<EnumData *>(found)->value << " is the enum value" << std::endl;
使用std::map<const char *,Enum>
,这是最佳选择。
以下代码演示了方法2和3,方法1很明显
enum Enum {
InvalidEnumValue,
EnumValue1,
EnumValue2,
EnumCount
};
struct EnumData {
const char *name;
Enum value;
};
static EnumData enums[EnumCount] = {
{"EnumValue1", EnumValue1},
{"EnumValue2", EnumValue2},
{"InvalidEnumValue", InvalidEnumValue}
};
int compare_enums(const void *const lhs, const void *const rhs)
{
return strcmp(reinterpret_cast<const EnumData *>(lhs)->name,
reinterpret_cast<const EnumData *>(rhs)->name);
}
Enum find_enum_value_with_bsearch(const char *const name)
{
EnumData key;
void *found;
key.name = name;
found = bsearch(&key, enums, EnumCount, sizeof(EnumData), compare_enums);
if (found == NULL)
return InvalidEnumValue;
return reinterpret_cast<EnumData *>(found)->value;
}
int
main()
{
Enum value;
std::map<const char *,Enum> enumsMap;
enumsMap["EnumValue1"] = EnumValue1;
enumsMap["EnumValue2"] = EnumValue2;
value = find_enum_value_with_bsearch("EnumValue2");
std::cerr << value << std::endl;
std::cerr << enumsMap["EnumValue1"] << std::endl;
}