C ++ 11自动创建整数到枚举值映射

耶康林

我需要创建一个intenum的映射(我正在读取文件中的整数,并且需要enum在运行时从中创建一个整数。)我可以手动创建一个映射,如下例所示。但是,这是一个琐碎的示例,我的枚举中只有几个(即七个)元素。

我的现实世界问题中有数百个元素enum class我不需要打印真实世界的名称enum,但是我确实需要获取enum给定整数值。我已经enum class创建了,并且想要一种自动的方法来创建一个从整数到枚举值的映射。

我正在寻求自动创建我已调用的地图,WeekMap以便可以将其传递给整数并获取enum值。这有可能吗?请告诉我是。

// Compile with:
//      clang++ -std=c++11 -stdlib=libc++ enum_test.cpp -o enum_test
// 

#include <iostream>
#include <string>
#include <map>

enum class Days {
    SUNDAY    = 1,
    MONDAY    = 2,
    TUESDAY   = 3,
    WEDNESDAY = 4,
    THURSDAY  = 5,
    FRIDAY    = 6,
    SATURDAY  = 7
};

std::ostream& operator<< (std::ostream& os, const Days& day){
    os << static_cast<std::underlying_type<Days>::type>(day);
    return os;
}

std::map<unsigned int, Days> WeekMap{
    {1, Days::SUNDAY},
    {2, Days::MONDAY},
    {3, Days::TUESDAY},
    {4, Days::WEDNESDAY},
    {5, Days::THURSDAY},
    {6, Days::FRIDAY},
    {7, Days::SATURDAY},
};

// Return the day of the week
Days WhatDay(unsigned int D){
    return WeekMap[D];
}

int main() {

    std::cout << "\nLearning how to 'cout' enums." << std::endl;

    Days myDay = Days::MONDAY;

    std::cout << "\nMonday is day: " << myDay << "\n" << std::endl;

    for (int i=1; i<8; i++){
        std::cout << "Day number: " << i << " is " << WhatDay(i) << std::endl;
    }

    return 0;
}
z

您不需要map您的WhatDay函数可以这样写:

Days WhatDay (unsigned int D) {
    return static_cast<Days>(D);
}

从效率的角度来看,这基本上是免费的。但是出于效率和可靠性的考虑,您可能要确保自己enum的基础类型确实是int(或更大或更小的东西):

enum class Days : int {
    ...
};

但是,使用此方法将失去的是错误检查。您将无法检查整数是否为有效的枚举值;尤其是当您的枚举值不连续时。

UPDATE 2(下面是Update 1!)要某种程度上自动创建这种enum,以及许多其他代码,可以使用以下技术:

您首先以通用格式写下您感兴趣的数据:

#define EXPAND_VALUES(action)           \
    action (1, SUNDAY,    "Sunday")     \
    action (2, MONDAY,    "Monday")     \
    action (3, TUESDAY,   "Tuesday")    \
    action (4, WEDNESDAY, "Wednesday")  \
    action (5, THURSDAY,  "Thursday")   \
    action (6, FRIDAY,    "Friday")     \
    action (7, SATURDAY,  "Saturday")
    // Note the lack of a separator after the entries; this is more flexible.

这是我所拥有的关于每个条目的全部信息,形式一般(即传递给名为的未知函数之类的东西)action

现在,要定义枚举,我们可以简单地说:

#define DEF_ENUM(i,v,s) v = i,
enum class Days : int { EXPAND_VALUES(DEF_ENUM) };
#undef DEF_ENUM

作为进一步的示例,您可以定义所需的映射,以及另一个将enum映射到字符串的表,如下所示:

#define DEF_MAP(i,v,s)  {i, Days::v},
std::map<int, Days> WeekMap { EXPAND_VALUES(DEF_MAP) };
#undef DEF_MAP

#define DEF_STR_MAP(i,v,s)  {Days::v, s},
std::map<Days, std::string> WeekStrMap { EXPAND_VALUES(DEF_STR_MAP) };
#undef DEF_STR_MAP

(此示例代码在Ideone上可用。)

请注意此技术对您的作用。如果没有在数据定义的任何冗余,获得尽可能多的数据结构的定义,数组的初始化,switch语句来的情况下,if- else if-else你想要的数据进行结构等。所有这些都是在编译时(或之前)完成的,没有任何麻烦。

这是一种非常强大的技术,可能对您有用(也可能没有)。


更新1(针对更新的问题):

不可以,无法enum在C ++中创建运行时。如果没有更多的编译器,则无法在运行时为编译器创建新类型(如果确实要这样做)。

但是,由于enumC ++中的s绝对不提供运行时功能,因此在运行时,enum具有相同基础类型的两个s之间没有区别或实际上是在anenum和an之间int(如果int是该类型的基础类型enum)。

因此,我建议这样做:您定义一个empty enum,并WhatDay像以前一样编写函数。一切都会好起来的!(因为您不需要边界检查。)

具体来说,我的建议是:

enum class Days : int { /*really, really empty!*/ };

Days WhatDay (unsigned int D) {
    return static_cast<Days>(D);
}

之所以可行,是因为在我看来您不知道编译时的枚举值,并且编译器不在乎enum运行时的a值没人做到!

而且,如果您要进行错误和范围检查,建议您使用“间隔树”(在Wikipedia上进行阅读)。enum在运行时从文件中读取时,请填充此树(这是您唯一的数据结构)填充),然后WhatDay根据它检查传递给函数的每个值

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C ++ 11自动创建整数到枚举值映射

来自分类Dev

C ++ 11将枚举转换为整数

来自分类Dev

通过引用或值枚举C ++ 11类

来自分类Dev

在C ++中将枚举值用作映射中的条目

来自分类Dev

C ++ 11如何通过int值获取枚举类的值?

来自分类Dev

如何定义包含整数作为值的C#枚举?

来自分类Dev

我的 C 函数没有返回正确的整数到二进制值

来自分类Dev

连续枚举C ++ 11

来自分类Dev

从Prolog传递任意大小的整数到C

来自分类Dev

C ++使用模板为特定的枚举值创建方法

来自分类Dev

C ++枚举值

来自分类Dev

C ++ 11映射值的迭代器(简单和透明)

来自分类Dev

创建一个以整数为键,以枚举为值的映射

来自分类Dev

C ++ 11自动转换

来自分类Dev

自动推导其类型时,将C ++ 11枚举类作为模板传递

来自分类Dev

C ++ 11 /自动为我分配布尔值?

来自分类Dev

如何将不同的C ++类映射到枚举类值

来自分类Dev

c警告消息:非零整数到指针的转换

来自分类Dev

c警告消息:非零整数到指针的转换

来自分类Dev

AVR C:整数到十六进制地址

来自分类Dev

C位电平整数到浮点转换的意外输出

来自分类Dev

映射到方法c ++ 11

来自分类Dev

C ++从枚举值获取位移

来自分类Dev

我可以在C ++ 11中使用键和值均为枚举类的std :: map吗?

来自分类Dev

枚举是C ++中的宏还是整数变量?

来自分类Dev

如何在vim中创建映射以自动执行.h c ++文件的ifdef命令

来自分类Dev

整数到枚举转换的static_cast

来自分类Dev

整数到枚举转换的static_cast

来自分类Dev

在什么情况下我应该在C ++ 11中为枚举类使用固定宽度的整数