我声明了枚举类型,
enum WeekEnum
{
Mon = 0;
Tue = 1;
Wed = 2;
Thu = 3;
Fri = 4;
Sat = 5;
Sun = 6;
};
当我已经有项目值“0,1等”时,如何获得项目名称“Mon,Tue等”
我已经有了这个功能
Log(Today is "2", enjoy! );
现在我想要输出
今天是星期三,享受
答案 0 :(得分:25)
你不能直接,C ++中的enum
不像Java枚举。
通常的方法是创建std::map<WeekEnum,std::string>
。
std::map<WeekEnum,std::string> m;
m[Mon] = "Monday";
//...
m[Sun] = "Sunday";
答案 1 :(得分:9)
不,你无法从C ++中的值中获取“名称”,因为在编译时会丢弃所有符号。
您可能需要这种方式X Macros
答案 2 :(得分:7)
枚举是一种反向数组。我相信你想要的是:
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.
答案 3 :(得分:6)
您可以定义执行输出的运算符。
std::ostream& operator<<(std::ostream& lhs, WeekEnum e) {
switch(e) {
case Monday: lhs << "Monday"; break;
.. etc
}
return lhs;
}
答案 4 :(得分:4)
这是使用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;
}
现场演示:https://ideone.com/bPAVTM
输出:
Enum value: 3
Name string: Thursday
Work day: true
Enum value: 6
Name string: Sunday
Work day: false
答案 5 :(得分:1)
当我已经拥有时,如何获得项目名称“Mon,Tue等” 项目值“0,1,等”
在一些较旧的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:这在枚举值和函数之间建立了“病态依赖”...这意味着如果更改枚举,则必须更改要匹配的函数。我想即使对于std :: map也是如此。
我依稀记得我们发现了一个从枚举代码中生成函数代码的实用程序。枚举表的长度已增长到几百......在某些时候,编写代码来编写代码可能是一个合理的选择。
注意 -
在嵌入式系统增强工作中,我的团队更换了许多用于将enum int值映射到其文本字符串的空终止字符串表(100+?)。
表的问题在于,超出范围的值通常没有被注意到,因为许多这些表被收集到一个代码/内存区域中,这样超出范围的值超过了指定的表结束( s)并从一些后续表中返回一个以null结尾的字符串。
使用function-with-switch语句还允许我们在switch的default子句中添加一个assert。断言在测试期间发现了几个编码错误,我们的断言被绑定到我们的现场技术人员可以搜索的static-ram-system-log中。
答案 6 :(得分:0)
我的技术非常成功,类似于@RolandXu指向的X宏。我们也大量使用了stringize运算符。当您拥有一个应用程序域时,该技术可以减轻维护的噩梦,其中项目既可以作为字符串也可以作为数字标记出现。
当机器可读文档可用时,它特别方便,因此可以自动生成宏X(...)行。新文档将立即导致一致的程序更新,涵盖字符串,枚举和在两个方向之间进行翻译的词典。 (我们正在处理PCL6令牌)。
虽然预处理器代码看起来很丑陋,但所有这些技术细节都可以隐藏在头文件中,这些文件永远不必再次触及,源文件也不会。一切都是类型安全的。唯一改变的是包含所有X(...)行的文本文件,这可能是自动生成的。
答案 7 :(得分:0)
如果您知道与它们的值相关的实际枚举标签,则可以使用容器和C ++ 17的std::string_view
通过[
]
运算符快速访问值及其字符串表示形式同时自己跟踪。 std::string_view
仅在创建时分配内存。如果希望它们在运行时可用,还可以用static constexpr
指定它们,以节省更多性能。这个小型控制台应用程序应该相当快。
#include <iostream>
#include <string_view>
#include <tuple>
int main() {
enum class Weekdays { //default behavior starts at 0 and iterates by 1 per entry
Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
};
static constexpr std::string_view Monday = "Monday";
static constexpr std::string_view Tuesday = "Tuesday";
static constexpr std::string_view Wednesday = "Wednesday";
static constexpr std::string_view Thursday = "Thursday";
static constexpr std::string_view Friday = "Friday";
static constexpr std::string_view Saturday = "Saturday";
static constexpr std::string_view Sunday = "Sunday";
static constexpr std::string_view opener = "enum[";
static constexpr std::string_view closer = "] is ";
static constexpr std::string_view semi = ":";
std::pair<Weekdays, std::string_view> Weekdays_List[] = {
std::make_pair(Weekdays::Monday, Monday),
std::make_pair(Weekdays::Tuesday, Tuesday),
std::make_pair(Weekdays::Wednesday, Wednesday),
std::make_pair(Weekdays::Thursday, Thursday),
std::make_pair(Weekdays::Friday, Friday),
std::make_pair(Weekdays::Saturday, Saturday),
std::make_pair(Weekdays::Sunday, Sunday)
};
for (int i=0;i<sizeof(Weekdays_List)/sizeof(Weekdays_List[0]);i++) {
std::cout<<opener<<i<<closer<<Weekdays_List[(int)i].second<<semi\
<<(int)Weekdays_List[(int)i].first<<std::endl;
}
return 0;
}
输出:
enum[0] is Monday:0
enum[1] is Tuesday:1
enum[2] is Wednesday:2
enum[3] is Thursday:3
enum[4] is Friday:4
enum[5] is Saturday:5
enum[6] is Sunday:6
答案 8 :(得分:0)
在GCC上,可能看起来像这样:
const char* WeekEnumNames [] = {
[Mon] = "Mon",
[Tue] = "Tue",
[Wed] = "Wed",
[Thu] = "Thu",
[Fri] = "Fri",
[Sat] = "Sat",
[Sun] = "Sun",
};
答案 9 :(得分:0)
我更喜欢的解决方案是像这样混合数组和ostream:
std::ostream& operator<<(std::ostream& lhs, WeekEnum e) {
static const std::array<std::string, 7> WEEK_STRINGS = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
return os << WEEK_STRINGS[statuc_cast<WeekEnum>(e)]
}
cout << "Today is " << WeekEnum::Monday;
我还建议使用枚举类而不是枚举