如何从其值中获取枚举项名称

时间:2021-11-25 11:08:50

I declared a enum type as this,

我宣布一个枚举类型,

enum WeekEnum
{
Mon = 0;
Tue = 1;
Wed = 2;
Thu = 3;
Fri = 4;
Sat = 5;
Sun = 6;
};

How can I get the item name "Mon, Tue, etc" when I already have the item value "0, 1, etc."

当我已经有项目值“0,1,等”时,如何获得项目名称“Mon,Tue等”

I already have a function as this

我已经有了这个功能

Log(Today is "2", enjoy! );

记录(今天是“2”,享受!);

And now I want the output below

现在我想要下面的输出

Today is Wed, enjoy

今天是星期三,享受

7 个解决方案

#1


21  

You can't directly, enum in C++ are not like Java enums.

你不能直接,在C ++中枚举不像Java枚举。

The usual approach is to create a std::map<WeekEnum,std::string>.

通常的方法是创建一个std :: map ,std>

std::map<WeekEnum,std::string> m;
m[Mon] = "Monday";
//...
m[Sun] = "Sunday";

#2


9  

no, you have no way to get the "name" from the value in C++ because all the symbols are discarded in compiling.

不,你无法从C ++中的值中获取“名称”,因为在编译时会丢弃所有符号。

You may need this way X Macros

您可能需要这种方式X宏

#3


7  

An enumeration is something of an inverse-array. What I believe you want is this:

枚举是反向数组的东西。我相信你想要的是:

const char * Week[] = { "", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };  // The blank string at the beginning is so that Sunday is 1 instead of 0.
cout << "Today is " << Week[2] << ", enjoy!";  // Or whatever you'de like to do with it.

#4


5  

You can define an operator that performs the output.

您可以定义执行输出的运算符。

std::ostream& operator<<(std::ostream& lhs, WeekEnum e) {
    switch(e) {
    case Monday: lhs << "Monday"; break;
    .. etc
    }
    return lhs;
}

#5


1  

How can I get the item name "Mon, Tue, etc" when I already have the item value "0, 1, etc."

当我已经有项目值“0,1,等”时,如何获得项目名称“Mon,Tue等”

On some older C code (quite some time ago), I found code analogous to:

在一些较旧的C代码(很久以前),我发现代码类似于:

std::string weekEnumToStr(int n)
{
   std::string s("unknown");
   switch (n)
   {
   case 0: { s = "Mon"; } break;
   case 1: { s = "Tue"; } break;
   case 2: { s = "Wed"; } break;
   case 3: { s = "Thu"; } break;
   case 4: { s = "Fri"; } break;
   case 5: { s = "Sat"; } break;
   case 6: { s = "Sun"; } break;
   }
   return s;
}

Con: This establishes a "pathological dependency" between the enumeration values and the function... meaning if you change the enum you must change the function to match. I suppose this is true even for a std::map.

Con:这在枚举值和函数之间建立了“病态依赖性”......这意味着如果更改枚举,则必须更改要匹配的函数。我想即使对于std :: map也是如此。

I vaguely remember we found a utility to generate the function code from the enum code. The enum table length had grown to several hundred ... and at some point it is maybe a sound choice to write code to write code.

我依稀记得我们发现了一个从枚举代码中生成函数代码的实用程序。枚举表的长度已增长到几百......在某些时候,编写代码来编写代码可能是一个合理的选择。


Note -

in an embedded system enhancement effort, my team replaced many tables (100+?) of null-terminated-strings used to map enum int values to their text strings.

在嵌入式系统增强工作中,我的团队更换了许多用于将枚举int值映射到其文本字符串的空终止字符串表(100+?)。

The problem with the tables was that a value out of range was often not noticed because many of these tables were gathered into one region of code / memory, such that a value out-of-range reached past the named table end(s) and returned a null-terminated-string from some subsequent table.

这些表的问题在于,超出范围的值通常没有被注意到,因为许多这些表被收集到一个代码/内存区域中,这样超出范围的值超过了指定的表结束和从一些后续表中返回一个以null结尾的字符串。

Using the function-with-switch statement also allowed us to add an assert in the default clause of the switch. The asserts found several more coding errors during test, and our asserts were tied into a static-ram-system-log our field techs could search.

使用function-with-switch语句还允许我们在switch的default子句中添加一个assert。断言在测试期间发现了几个编码错误,我们的断言被绑定到我们的现场技术人员可以搜索的静态ram-system-log中。

#6


1  

Here is another neat trick to define enum using X Macro:

这是使用X Macro定义枚举的另一个巧妙技巧:

#include <iostream>

#define WEEK_DAYS \
X(MON, "Monday", true) \
X(TUE, "Tuesday", true) \
X(WED, "Wednesday", true) \
X(THU, "Thursday", true) \
X(FRI, "Friday", true) \
X(SAT, "Saturday", false) \
X(SUN, "Sunday", false)

#define X(day, name, workday) day,
enum WeekDay : size_t
{
    WEEK_DAYS
};
#undef X

#define X(day, name, workday) name,
char const *weekday_name[] =
{
    WEEK_DAYS
};
#undef X

#define X(day, name, workday) workday,
bool weekday_workday[]
{
    WEEK_DAYS
};
#undef X

int main()
{
    std::cout << "Enum value: " << WeekDay::THU << std::endl;
    std::cout << "Name string: " << weekday_name[WeekDay::THU] << std::endl;
    std::cout << std::boolalpha << "Work day: " << weekday_workday[WeekDay::THU] << std::endl;

    WeekDay wd = SUN;
    std::cout << "Enum value: " << wd << std::endl;
    std::cout << "Name string: " << weekday_name[wd] << std::endl;
    std::cout << std::boolalpha << "Work day: " << weekday_workday[wd] << std::endl;

    return 0;
}

Live Demo: https://ideone.com/bPAVTM

现场演示:https://ideone.com/bPAVTM

Outputs:

Enum value: 3
Name string: Thursday
Work day: true
Enum value: 6
Name string: Sunday
Work day: false

#7


0  

I have had excellent success with a technique which resembles the X macros pointed to by @RolandXu. We made heavy use of the stringize operator, too. The technique mitigates the maintenance nightmare when you have an application domain where items appear both as strings and as numerical tokens.

我的技术非常成功,类似于@RolandXu指向的X宏。我们也大量使用了stringize运算符。当您拥有一个应用程序域时,该技术可以减轻维护噩梦,其中项目既可以作为字符串也可以作为数字标记出现。

It comes in particularily handy when machine readable documentation is available so that the macro X(...) lines can be auto-generated. A new documentation would immediately result in a consistent program update covering the strings, enums and the dictionaries translating between them in both directions. (We were dealing with PCL6 tokens).

当机器可读文档可用时,它特别方便,因此可以自动生成宏X(...)行。新文档将立即导致一致的程序更新,涵盖字符串,枚举和在两个方向之间进行翻译的词典。 (我们正在处理PCL6令牌)。

And while the preprocessor code looks pretty ugly, all those technicalities can be hidden in the header files which never have to be touched again, and neither do the source files. Everything is type safe. The only thing that changes is a text file containing all the X(...) lines, and that is possibly auto generated.

虽然预处理器代码看起来很丑陋,但所有这些技术细节都可以隐藏在头文件中,这些文件永远不必再次触及,源文件也不会。一切都是类型安全的。唯一改变的是包含所有X(...)行的文本文件,并且可能是自动生成的。

#1


21  

You can't directly, enum in C++ are not like Java enums.

你不能直接,在C ++中枚举不像Java枚举。

The usual approach is to create a std::map<WeekEnum,std::string>.

通常的方法是创建一个std :: map ,std>

std::map<WeekEnum,std::string> m;
m[Mon] = "Monday";
//...
m[Sun] = "Sunday";

#2


9  

no, you have no way to get the "name" from the value in C++ because all the symbols are discarded in compiling.

不,你无法从C ++中的值中获取“名称”,因为在编译时会丢弃所有符号。

You may need this way X Macros

您可能需要这种方式X宏

#3


7  

An enumeration is something of an inverse-array. What I believe you want is this:

枚举是反向数组的东西。我相信你想要的是:

const char * Week[] = { "", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };  // The blank string at the beginning is so that Sunday is 1 instead of 0.
cout << "Today is " << Week[2] << ", enjoy!";  // Or whatever you'de like to do with it.

#4


5  

You can define an operator that performs the output.

您可以定义执行输出的运算符。

std::ostream& operator<<(std::ostream& lhs, WeekEnum e) {
    switch(e) {
    case Monday: lhs << "Monday"; break;
    .. etc
    }
    return lhs;
}

#5


1  

How can I get the item name "Mon, Tue, etc" when I already have the item value "0, 1, etc."

当我已经有项目值“0,1,等”时,如何获得项目名称“Mon,Tue等”

On some older C code (quite some time ago), I found code analogous to:

在一些较旧的C代码(很久以前),我发现代码类似于:

std::string weekEnumToStr(int n)
{
   std::string s("unknown");
   switch (n)
   {
   case 0: { s = "Mon"; } break;
   case 1: { s = "Tue"; } break;
   case 2: { s = "Wed"; } break;
   case 3: { s = "Thu"; } break;
   case 4: { s = "Fri"; } break;
   case 5: { s = "Sat"; } break;
   case 6: { s = "Sun"; } break;
   }
   return s;
}

Con: This establishes a "pathological dependency" between the enumeration values and the function... meaning if you change the enum you must change the function to match. I suppose this is true even for a std::map.

Con:这在枚举值和函数之间建立了“病态依赖性”......这意味着如果更改枚举,则必须更改要匹配的函数。我想即使对于std :: map也是如此。

I vaguely remember we found a utility to generate the function code from the enum code. The enum table length had grown to several hundred ... and at some point it is maybe a sound choice to write code to write code.

我依稀记得我们发现了一个从枚举代码中生成函数代码的实用程序。枚举表的长度已增长到几百......在某些时候,编写代码来编写代码可能是一个合理的选择。


Note -

in an embedded system enhancement effort, my team replaced many tables (100+?) of null-terminated-strings used to map enum int values to their text strings.

在嵌入式系统增强工作中,我的团队更换了许多用于将枚举int值映射到其文本字符串的空终止字符串表(100+?)。

The problem with the tables was that a value out of range was often not noticed because many of these tables were gathered into one region of code / memory, such that a value out-of-range reached past the named table end(s) and returned a null-terminated-string from some subsequent table.

这些表的问题在于,超出范围的值通常没有被注意到,因为许多这些表被收集到一个代码/内存区域中,这样超出范围的值超过了指定的表结束和从一些后续表中返回一个以null结尾的字符串。

Using the function-with-switch statement also allowed us to add an assert in the default clause of the switch. The asserts found several more coding errors during test, and our asserts were tied into a static-ram-system-log our field techs could search.

使用function-with-switch语句还允许我们在switch的default子句中添加一个assert。断言在测试期间发现了几个编码错误,我们的断言被绑定到我们的现场技术人员可以搜索的静态ram-system-log中。

#6


1  

Here is another neat trick to define enum using X Macro:

这是使用X Macro定义枚举的另一个巧妙技巧:

#include <iostream>

#define WEEK_DAYS \
X(MON, "Monday", true) \
X(TUE, "Tuesday", true) \
X(WED, "Wednesday", true) \
X(THU, "Thursday", true) \
X(FRI, "Friday", true) \
X(SAT, "Saturday", false) \
X(SUN, "Sunday", false)

#define X(day, name, workday) day,
enum WeekDay : size_t
{
    WEEK_DAYS
};
#undef X

#define X(day, name, workday) name,
char const *weekday_name[] =
{
    WEEK_DAYS
};
#undef X

#define X(day, name, workday) workday,
bool weekday_workday[]
{
    WEEK_DAYS
};
#undef X

int main()
{
    std::cout << "Enum value: " << WeekDay::THU << std::endl;
    std::cout << "Name string: " << weekday_name[WeekDay::THU] << std::endl;
    std::cout << std::boolalpha << "Work day: " << weekday_workday[WeekDay::THU] << std::endl;

    WeekDay wd = SUN;
    std::cout << "Enum value: " << wd << std::endl;
    std::cout << "Name string: " << weekday_name[wd] << std::endl;
    std::cout << std::boolalpha << "Work day: " << weekday_workday[wd] << std::endl;

    return 0;
}

Live Demo: https://ideone.com/bPAVTM

现场演示:https://ideone.com/bPAVTM

Outputs:

Enum value: 3
Name string: Thursday
Work day: true
Enum value: 6
Name string: Sunday
Work day: false

#7


0  

I have had excellent success with a technique which resembles the X macros pointed to by @RolandXu. We made heavy use of the stringize operator, too. The technique mitigates the maintenance nightmare when you have an application domain where items appear both as strings and as numerical tokens.

我的技术非常成功,类似于@RolandXu指向的X宏。我们也大量使用了stringize运算符。当您拥有一个应用程序域时,该技术可以减轻维护噩梦,其中项目既可以作为字符串也可以作为数字标记出现。

It comes in particularily handy when machine readable documentation is available so that the macro X(...) lines can be auto-generated. A new documentation would immediately result in a consistent program update covering the strings, enums and the dictionaries translating between them in both directions. (We were dealing with PCL6 tokens).

当机器可读文档可用时,它特别方便,因此可以自动生成宏X(...)行。新文档将立即导致一致的程序更新,涵盖字符串,枚举和在两个方向之间进行翻译的词典。 (我们正在处理PCL6令牌)。

And while the preprocessor code looks pretty ugly, all those technicalities can be hidden in the header files which never have to be touched again, and neither do the source files. Everything is type safe. The only thing that changes is a text file containing all the X(...) lines, and that is possibly auto generated.

虽然预处理器代码看起来很丑陋,但所有这些技术细节都可以隐藏在头文件中,这些文件永远不必再次触及,源文件也不会。一切都是类型安全的。唯一改变的是包含所有X(...)行的文本文件,并且可能是自动生成的。