假设我们有一个枚举,如下所示:

enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};

我想创建这个枚举的一个实例,并初始化它与一个适当的值,所以我做:

Days day = Days.Saturday;

现在我想用一个现有的enum值检查我的变量或实例,所以我这样做:

if (day == Days.Saturday)
{
    std::cout << "Ok its Saturday";
}

这给了我一个编译错误:

错误:在`之前期望主表达式。“令牌

所以要明确的是,这两者的区别是什么

if (day == Days.Saturday) // Causes compilation error

and

if (day == Saturday)

?

这两个实际上指的是什么,一个是OK,一个导致编译错误?


当前回答

如果我们想要严格的类型安全和有作用域的enum,在c++ 11中使用enum类是很好的。

如果我们必须在c++ 98中工作,我们可以使用InitializeSahib,San给出的建议来启用作用域enum。

如果我们还想要严格的类型安全,下面的代码可以实现类似enum的东西。

#include <iostream>
class Color
{
public:
    static Color RED()
    {
        return Color(0);
    }
    static Color BLUE()
    {
        return Color(1);
    }
    bool operator==(const Color &rhs) const
    {
        return this->value == rhs.value;
    }
    bool operator!=(const Color &rhs) const
    {
        return !(*this == rhs);
    }

private:
    explicit Color(int value_) : value(value_) {}
    int value;
};

int main()
{
    Color color = Color::RED();
    if (color == Color::RED())
    {
        std::cout << "red" << std::endl;
    }
    return 0;
}

代码修改自《Effective c++ 3rd: Item 18》一书中的Month类示例

其他回答

遗憾的是,枚举的元素是“全局的”。你可以通过day = Saturday来访问它们。这意味着你不能有枚举A {A, b};and enum B {B, a};因为他们是相冲突的。

如果我们想要严格的类型安全和有作用域的enum,在c++ 11中使用enum类是很好的。

如果我们必须在c++ 98中工作,我们可以使用InitializeSahib,San给出的建议来启用作用域enum。

如果我们还想要严格的类型安全,下面的代码可以实现类似enum的东西。

#include <iostream>
class Color
{
public:
    static Color RED()
    {
        return Color(0);
    }
    static Color BLUE()
    {
        return Color(1);
    }
    bool operator==(const Color &rhs) const
    {
        return this->value == rhs.value;
    }
    bool operator!=(const Color &rhs) const
    {
        return !(*this == rhs);
    }

private:
    explicit Color(int value_) : value(value_) {}
    int value;
};

int main()
{
    Color color = Color::RED();
    if (color == Color::RED())
    {
        std::cout << "red" << std::endl;
    }
    return 0;
}

代码修改自《Effective c++ 3rd: Item 18》一书中的Month类示例

不要把enum看成一组对象,把它看成一个整数,其中每个数值都有一个名称,所以enum Days最好声明为enum Day。 如果你想把它包含在一个命名结构中,把enum Day放在一个结构Days中,就像这样:

struct Days{
    enum Day{
        Saturday,
        Sunday,
        Tuesday,
        Wednesday,
        Thursday,
        Friday
    };
};

然后您可以像这样称呼它们Days::Saturday,类型为Days::Day

如果您仍在使用c++ 03并希望使用枚举,则应该在命名空间中使用枚举。 例如:

namespace Daysofweek{
enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
}

你可以像这样在命名空间之外使用枚举,

Daysofweek::Days day = Daysofweek::Saturday;

if (day == Daysofweek::Saturday)
{
    std::cout<<"Ok its Saturday";
}

虽然c++(不包括c++ 11)有枚举,但枚举中的值被“泄露”到全局命名空间中。 如果你不想让它们泄露(并且不需要使用枚举类型),考虑以下:

class EnumName {  
   public:   
      static int EnumVal1;  
      (more definitions)  
};  
EnumName::EnumVal1 = {value};  
if ([your value] == EnumName::EnumVal1)  ...