如何在C++中使用枚举

Rik*_*ika 202 c++ enums

假设我们有enum以下内容:

enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Run Code Online (Sandbox Code Playgroud)

我想创建一个这样的实例enum并用适当的值初始化它,所以我做:

Days day = Days.Saturday;
Run Code Online (Sandbox Code Playgroud)

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

if (day == Days.Saturday)
{
    std::cout << "Ok its Saturday";
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个编译错误:

错误:'.'之前的预期primary-expression 代币

所以要说清楚,说:有什么区别:

if (day == Days.Saturday) // Causes compilation error
Run Code Online (Sandbox Code Playgroud)

if (day == Saturday)
Run Code Online (Sandbox Code Playgroud)

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

Moo*_*uck 326

这段代码错了:

enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Days.Saturday;
if (day == Days.Saturday)
Run Code Online (Sandbox Code Playgroud)

因为Days不是范围,也不是对象.这是一种类型.而类型本身没有成员.你写的是相当于std::string.clear. std::string是一种类型,所以你不能使用.它.您.在类的实例上使用.

不幸的是,枚举是神奇的,所以类比就停在那里.因为有了类,你可以做std::string::clear一个指向成员函数的指针,但是在C++ 03中,它Days::Sunday是无效的.(这很难过).这是因为C++(有点)向后兼容C,而C没有名称空间,因此枚举必须在全局名称空间中.所以语法很简单:

enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Saturday;
if (day == Saturday)
Run Code Online (Sandbox Code Playgroud)

幸运的是,Mike Seymour观察到这已在C++ 11中得到解决.更改enumenum class它获得自己的范围; 所以Days::Sunday不仅有效,而且是唯一的访问方式Sunday.快乐的时光!

  • 幸运的是,您的投诉已在C++ 11中得到解决.将`enum`改为`enum class`,它有自己的范围; 所以`Days :: Sunday`不仅有效,而且是访问`Sunday`的唯一途径.快乐的时光! (240认同)
  • 一定要喜欢C++错误消息......他们证明这种语言很难提供很好的反馈.我认为'primary-expression'是一个对象或范围或其他不属于类型的东西.也许Type是'次要表达'.而C++开发人员可能称之为"点运算符"的C++编译器只能调用'标记'.当我很难理解错误信息时,我认为语言有问题. (9认同)
  • @Travis:http://en.cppreference.com/w/cpp/language/expressions#Primary_expressions.主表达式只是表达式中的第一个东西,通常是名称或变量或文字.至于第二部分,我没有看到''.'之间有很大的区别.token`和`dot operator`,除了它是一个令牌而不是一个运算符,它显示的是确切的符号,而不是名称. (4认同)

mat*_*975 24

这足以声明你的枚举变量并进行比较:

enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Saturday;
if (day == Saturday) {
    std::cout << "Ok its Saturday";
}
Run Code Online (Sandbox Code Playgroud)

  • @Hossein:因为这不是C++中的枚举工作方式.无范围枚举将其值放入周围的命名空间中; scoped的(`enum class`,2011年新增)有自己的范围,可以使用范围运算符`Days :: Saturday`访问.成员访问运算符(`.`)仅用于访问类成员. (7认同)
  • @Hossein:因为`Days`不是范围,也不是对象.这是一种类型.和类型_themelves_没有成员.由于同样的原因,`std :: string.clear`也无法编译. (2认同)

pb2*_*b2q 22

其中大部分应该会给你编译错误.

// note the lower case enum keyword
enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };
Run Code Online (Sandbox Code Playgroud)

现在,Saturday,Sunday等可以被用作顶级裸常量和Days可以用作一个类型:

Days day = Saturday;   // Days.Saturday is an error
Run Code Online (Sandbox Code Playgroud)

以后类似地测试:

if (day == Saturday)
    // ...
Run Code Online (Sandbox Code Playgroud)

这些enum值就像裸常量一样 - 它们是un -scoped - 只需要编译器的一些额外帮助:(除非你使用的是C++ 11 枚举类)它们不像对象或结构成员那样封装,例如,你不能把它们称为成员Days.

你会得到你正在寻找的C++ 11,它引入了enum class:

enum class Days
{
    SUNDAY,
    MONDAY,
    // ... etc.
}

// ...

if (day == Days::SUNDAY)
    // ...
Run Code Online (Sandbox Code Playgroud)

请注意,这个C++在几个方面与C略有不同,一个是C enum在声明变量时需要使用关键字:

// day declaration in C:
enum Days day = Saturday;
Run Code Online (Sandbox Code Playgroud)


小智 11

您可以根据需要使用技巧来使用范围,只需以这种方式声明枚举:

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

Days::type day = Days::Saturday;
if (day == Days::Saturday)
Run Code Online (Sandbox Code Playgroud)


Ale*_*rth 9

您正在寻找强类型枚举,这是C++11标准中可用的功能。它将枚举转换为具有范围值的类。

使用您自己的代码示例,它是:

  enum class Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
  Days day = Days::Saturday;

  if (day == Days::Saturday)  {
    cout << " Today is Saturday !" << endl;
  }
  //int day2 = Days::Sunday; // Error! invalid
Run Code Online (Sandbox Code Playgroud)

使用::作为访问器来枚举如果靶向C ++标准的现有C ++ 11将失败。但是一些旧的编译器不支持它,一些 IDE 只是覆盖了这个选项,并设置了一个旧的 C++ 标准。

如果您使用 GCC,请使用-std=c++11-std=gnu11启用 C+11 。

要开心!


Dea*_*ght 8

枚举不是使用一堆if语句,而是适合切换语句

我在我为游戏构建的关卡生成器中使用了一些枚举/开关组合.

编辑:另一件事,我看到你想要语法类似;

if(day == Days.Saturday)
etc
Run Code Online (Sandbox Code Playgroud)

你可以用C++做到这一点:

if(day == Days::Saturday)
etc
Run Code Online (Sandbox Code Playgroud)

这是一个非常简单的例子:

EnumAppState.h

#ifndef ENUMAPPSTATE_H
#define ENUMAPPSTATE_H
enum eAppState
{
    STARTUP,
    EDIT,
    ZONECREATION,
    SHUTDOWN,
    NOCHANGE
};
#endif
Run Code Online (Sandbox Code Playgroud)

Somefile.cpp

#include "EnumAppState.h"
eAppState state = eAppState::STARTUP;
switch(state)
{
case STARTUP:
    //Do stuff
    break;
case EDIT:
    //Do stuff
    break;
case ZONECREATION:
    //Do stuff
    break;
case SHUTDOWN:
    //Do stuff
    break;
case NOCHANGE:
    //Do stuff
    break;
}
Run Code Online (Sandbox Code Playgroud)

  • enum 只是 C++ 中的一种数据类型,所以像我上面在 .h 文件中所做的那样声明一个 enum,然后将该文件包含在您想要使用它的任何 .cpp 文件中,您就可以访问该 enum。刚刚注意到我忘记在我的 .cpp 示例中添加 #include。编辑。 (2认同)

bam*_*s53 6

这应该不适用于C++:

Days.Saturday
Run Code Online (Sandbox Code Playgroud)

Days不是包含您可以使用点运算符访问的成员的范围或对象.这种语法只是一种C#主义,在C++中是不合法的.

Microsoft长期以来一直使用C++扩展,允许您使用范围运算符访问标识符:

enum E { A, B, C };

A;
E::B; // works with Microsoft's extension
Run Code Online (Sandbox Code Playgroud)

但这在C++ 11之前是非标准的.在C++ 03中,枚举中声明的标识符仅存在于与枚举类型本身相同的范围内.

A;
E::B; // error in C++03
Run Code Online (Sandbox Code Playgroud)

C++ 11使得使用枚举名称限定枚举标识符是合法的,并且还引入了枚举类,这些枚举类为标识符创建了新的范围,而不是将它们放在周围的范围中.

A;
E::B; // legal in C++11

enum class F { A, B, C };

A; // error
F::B;
Run Code Online (Sandbox Code Playgroud)


San*_*San 6

如果您仍在使用C++ 03并且想要使用枚举,那么您应该在命名空间中使用枚举.例如:

namespace Daysofweek{
enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
}
Run Code Online (Sandbox Code Playgroud)

您可以在命名空间外使用枚举,如,

Daysofweek::Days day = Daysofweek::Saturday;

if (day == Daysofweek::Saturday)
{
    std::cout<<"Ok its Saturday";
}
Run Code Online (Sandbox Code Playgroud)


Grz*_*orz 5

可悲的是,枚举的元素是“全局的”。您可以通过执行访问它们day = Saturday。这意味着你不能拥有enum A { a, b } ;enum B { b, a } ;因为它们是冲突的。

  • 直到您在 C++11 中使用 `enum class`,即。在此之前,您必须制作虚拟课程。 (2认同)