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

时间:2012-07-30 01:04:31

标签: c++ enums

我声明了枚举类型,

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! );

现在我想要输出

  

今天是星期三,享受

10 个答案:

答案 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;

我还建议使用枚举类而不是枚举