C ++中的枚举和匿名枚举

时间:2013-07-24 10:52:54

标签: c++

1)以下代码显示枚举元素周三的索引。如何使其打印值而不是索引。

int main()
{
    enum day{sunday,monday,tuesday,wednesday,thursday,friday,saturday};
    day d=wednesday;
    cout<<d;
    return 0;
}

2)在什么情况下我更喜欢匿名枚举而不是枚举

7 个答案:

答案 0 :(得分:7)

1)。您的代码打印枚举的值,而不是索引。在您的特定示例中,索引与值相同(默认情况下,枚举的第一个值获取数值0,其余值获得连续增加的值。

检查:

int main()
{
    enum day{sunday = 5,monday,tuesday,wednesday,thursday,friday,saturday};
    day d=wednesday;
    cout<<d; // will print 8 (as in 5 + 1 + 1 + 1)
    return 0;
}

如果通过“打印值”表示打印“星期三”,则应该这样做:

enum day{sunday,monday,tuesday,wednesday,thursday,friday,saturday};

std::ostream& operator << (std::ostream& out, const day d)
{
    static const char *as_strings[] = {"sunday", "monday",
        "tuesday", "wednesday", "thursday", "friday", "saturday"
    };
    return out << as_strings[static_cast<int>(d)]; // this only works 
                 // for enum values starting from 0 and being consecutive
                 // otherwise you should use a switch(d) and 
                 // print each value separately
}

int main()
{
    day d=wednesday;
    cout<<d; // will print wednesday
    return 0;
}

编辑:

  

2)在什么情况下我更喜欢匿名枚举而非枚举

当您不需要将其作为参数传递时,您更喜欢匿名枚举,但需要为常量数值指定有意义的名称:

my_object record_to_myobject(record& r)
{
    enum {id, value1, value2}; // indexes within record
    int result_id = r[id]; // much more meaningful than r[0]
    int result_value1 = r[value1];
    int result_value2 = r[value2];
    return my_object{result_id, result_value1, result_value2};
}

在这里使用匿名枚举是很好的,因为在将值作为参数传递的地方,你需要一个int,而不是一个枚举类型。如果你需要枚举类型,那么你必须给它一个名字。否则,你没有。

答案 1 :(得分:2)

首先,语言没有提供任何映射方法 内部枚举值到字符串。它不能,真的;考虑:

enum Numbers {
    one = 1,
    two = 2,
    three = 3,
    un = 1,
    deux = 2,
    trois = 3
};

一旦你将枚举常量赋给了枚举变量,就可以了 包含数值,没有别的。如果是的话 上面的数值是2,系统怎么知道 是否应映射到twodeux

实际上,映射 在许多情况下都很有用。很久了 前段时间,我写了一个简单的解析器来生成映射代码; 它忽略了大部分C ++,在以下情况下不起作用。该 枚举被包装在宏中,它生成的代码不会 如果枚举是私有的或受保护的,则编译,并且它是未定义的 在上述情况下你得到的字符串,但我还是 发现它非常有用。

对于第二个问题:通常使用匿名枚举 枚举的唯一目的是生成常量。事情 像:

enum { maxSize = 4096 };

在您提供初始化之前被广泛使用 静态成员变量的常量。而且我经常发现它 方便使用匿名枚举定义位掩码,甚至 当实际值是某种无符号类型时。 比如:

enum {
    offsetMask = 0xF000,
    offsetShift = 12,
    NS = 0x100,
    CWR = 0x80,
    ECE = 0x40,
    URG = 0x20,
    ACK = 0x10,
    //  ...
};
uint16_t flags;
//  ...
flags = offset << offsetShift | ACK;

我不想声明我的变量有枚举;他们一定 正好是16位(根据TCP规范)。在C中, 我可能已经使用了#define,而在现代C ++中,我可能会 使用static uint16_t const成员变量,但通过out 我的大部分C ++职业,就像上面的那样 正常的解决方案。

答案 2 :(得分:0)

你必须手动维护枚举值的字符串“描述”数组,这很乏味且容易出错:

static const char *daydescs[] = {
    "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"
};

int main()
{
    enum day{sunday,monday,tuesday,wednesday,thursday,friday,saturday};
    day d=wednesday;
    cout<< daydescs[(unsigned)d];
    return 0;
}

答案 3 :(得分:0)

枚举是一个数字,字符串表示(例如星期三)是编译时表示。

您需要以下内容:

const char *dayname[] = {"sunday","monday","tuesday","wednesday","thursday","friday","saturday"};

...
cout << dayname[(unsigned)d];
...

答案 4 :(得分:0)

尝试以下代码:

int main()
{
    enum day{sunday,monday,tuesday,wednesday,thursday,friday,saturday};
    String days[7] = {"sunday","monday","tuesday","wednesday","thursday","friday","saturday"};
    day d=wednesday;
    cout<<days[d];
    return 0;
}

答案 5 :(得分:0)

1)如果您只想要整数值,可以编写operator <<重载:

template<typename _stream>
_stream& operator << (const day& value) {
  _stream << static_cast<int>(value);
  return _stream;
}

另外,请考虑使用枚举类而不是简单的枚举(如果您当然可以使用C ++ 11)。

2)我想说可能有1个这样的情况:命名空间常量,比如你有一个Person类,并希望有一些像MaxAgeMaxNameLength这样的类内常量。但即使在这种情况下,像enum class Settings这样的包装限制通常也是值得的。

答案 6 :(得分:0)

此主题的类型安全变体是使用enum class并将其用作std::map

中的键
#include <string>
#include <map>
#include <iostream>

int main()
{
    enum class day
    {
        sunday,
        monday,
        tuesday,
        wednesday,
        thursday,
        friday,
        saturday
    };    

    std::map<day,std::string> days = 
    {
        std::make_pair(day::sunday, "Sunday"),
        std::make_pair(day::monday, "Monday"),
        std::make_pair(day::tuesday, "Tuesday"),
        std::make_pair(day::wednesday, "Wednesday"),
        std::make_pair(day::thursday, "Thursday"),
        std::make_pair(day::friday, "Friday"),
        std::make_pair(day::saturday, "Saturday")
    };
    std::cout << days[day::sunday] << std::endl;
}

这意味着使用整数类型访问映射将导致编译时错误。

相关问题