2

我在结构中有一个枚举:

enum Days : uint8_t
{
  day1 =1,
  day2 =2,
  day2 =3
}

struct Hi
{
  Days days;
}

在编译时,我得到一个错误Scoped enums not available in this version。我需要我的所有枚举都是一种uint8_t类型并在结构中定义。

4

2 回答 2

5

即使在 C++11 之前,如果您注意所有枚举值都小于 128,您可以简单地将它们存储在 uint8_t 变量中。不过,这可能需要在使用它们时进行强制转换。这是将枚举值压缩到结构中的常用方法,尤其是在内存紧张的嵌入式代码中。如果您的代码使用这些结构的大量实例,此技术还可以提高您的数据缓存命中率。

enum Days
{
    Day1 =1,
    Day2 =2,
    Day3 =3
};
typedef uint8_t DaysTy;

// Totally optional, but allows you to send a 'DaysTy' to cout directly:
std::ostream& operator<<(std::ostream& s, const DaysTy& d)
{
    const char* txt="ILLEGAL";
    switch (d)
    {
        case Day1: txt = "Day1"; break;
        case Day2: txt = "Day2"; break;
        case Day3: txt = "Day3"; break;
    }
    s << txt;
    return s;
}

struct Hi
{
    DaysTy dayA;
    DaysTy dayB;
    DaysTy dayC;

    // Totally optional, but allows you to send a 'Hi' struct to cout directly:
    friend std::ostream& operator<<(std::ostream& s, const Hi& m);
};

// Totally optional, but allows you to send a 'Hi' struct to cout directly:
std::ostream& operator<<(std::ostream& s, const Hi& h)
{
    s << '[' << h.dayA << ',' << h.dayB << ',' << h.dayC << ']';
    return s;
}


int main()
{
    Hi aHiObject;
    aHiObject.dayA = Day3;
    aHiObject.dayB = Day2;
    aHiObject.dayC = Day1;

    std::cout << "my Hi object: " << aHiObject << '\n';
    if (aHiObject.dayA == Day1)
        std::cout << "Its dayA is Day1.\n";
    if (aHiObject.dayA == Day2)
        std::cout << "Its dayA is Day2.\n";
    if (aHiObject.dayA == Day3)
        std::cout << "Its dayA is Day3.\n";

    std::cout << "sizeof(aHiObject)      = " << sizeof(aHiObject) << " byte(s)\n"
                 "sizeof(aHiObject.dayA) = " << sizeof(aHiObject.dayA) << " byte(s)\n";

    std::cout << "Value '3' as a uint8_t: " << (uint8_t)3 << '\n';
    std::cout << "Value '3' as a DaysTy: "  << (DaysTy)3  << '\n';

    std::cout << "Value '4' as a uint8_t: " << (uint8_t)4 << '\n';
    std::cout << "Value '4' as a DaysTy: "  << (DaysTy)4  << '\n';
}

运行此代码会产生以下输出:

my Hi object: [Day3,Day2,Day1]
Its dayA is Day3.
sizeof(aHiObject)      = 3 byte(s)
sizeof(aHiObject.dayA) = 1 byte(s)
Value '3' as a uint8_t: Day3
Value '3' as a DaysTy: Day3
Value '4' as a uint8_t: ILLEGAL
Value '4' as a DaysTy: ILLEGAL

...顺便说一句,迈克西摩在下面的评论是正确的。尽管如此,这演示了一种可以将枚举值打包到 uint8_t 变量类型中的方法。

于 2013-08-14T15:29:57.203 回答
3

如果您正在编写 C++,并且您可以更新到现代编译器(或者可能在您的编译器中启用 C++11 支持),那么您的代码就可以了。

如果您正在编写 C 或历史悠久的 C++,那么您就不能——这些语言根本不允许您指定枚举的大小。您必须uint8_t在需要明确大小的地方使用,并在必要时进行转换:

struct Hi {
    uint8_t days;
};

Hi hi;

hi.days = static_cast<uint8_t>(day1);
Days d = static_cast<Days>(hi.days);
于 2013-08-14T15:46:19.573 回答