Как использовать перечисления в C++



предположим, что у нас есть enum следующим образом:



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


Я хочу создать экземпляр этого enum и инициализировать его с правильным значением, так что я делаю:



Days day = Days.Saturday;


теперь я хочу проверить мою переменную или экземпляр с существующим enum значение, поэтому я делаю:



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


это дает мне ошибку компиляции:




ошибка: ожидается первичное-выражение до ‘.- токен




Итак, чтобы быть ясным, что такое разница между словами:



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


и



if (day == Saturday)


?



что эти два на самом деле относятся, в том, что один в порядке, и один вызывает ошибку компиляции?

536   13  

13 ответов:

этот код не так:

enum Days { Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday};
Days day = Days.Saturday;
if(day == Days.Saturday)

потому что дни не является ни областью, ни объектом. Это типаж. И сами типы не имеют членов. То, что вы написали эквивалентно 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)

к счастью, Майк Сеймур замечает, что это было рассмотрено в C++11. Изменить enum до enum class и он получает свой собственный объем; так Days::Sunday не только действителен, но и является только способ доступа Sunday. Счастливые дни!

этого будет достаточно, чтобы объявить переменную enum и сравнить ее:

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

многое из этого должно дать вам ошибки компиляции.

// note the lower case enum keyword
enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };

теперь Saturday,Sunday и т. д. может использоваться как голые константы верхнего уровня, так и Days может использоваться как тип:

Days day = Saturday;   // Days.Saturday is an error

и так же позже, чтобы проверить:

if (day == Saturday)
    // ...

эти enum значения похожи на голые константы-они un - scoped - с небольшой дополнительной помощью от компилятора: (если вы не используете C++11 классов enum) они не инкапсулированные как объекты или элементы структуры, например, и вы не можете ссылаться на них как члены на Days.

вы будете иметь то, что вы ищете с C++11, который вводит enum class:

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

// ...

if (day == Days::SUNDAY)
    // ...

обратите внимание, что этот C++ немного отличается от C несколькими способами, один из которых заключается в том, что C требует использования enum ключевое слово при объявлении переменной:

// day declaration in C:
enum Days day = Saturday;

вы можете использовать трюк, чтобы использовать области, как вы хотите, просто объявить перечисление таким образом:

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

Days::type day = Days::Saturday;
if (day == Days::Saturday)

вместо того, чтобы использовать кучу if-операторов, перечисления хорошо поддаются переключению операторов

Я использую некоторые комбинации перечислений / переключателей в построителе уровней, который я создаю для своей игры.

EDIT: другое дело, я вижу, что вы хотите синтаксис похож на;

if(day == Days.Saturday)
etc

вы можете сделать это в C++:

if(day == Days::Saturday)
etc

вот очень простой пример:

EnumAppState.h

#ifndef ENUMAPPSTATE_H
#define ENUMAPPSTATE_H
enum eAppState
{
    STARTUP,
    EDIT,
    ZONECREATION,
    SHUTDOWN,
    NOCHANGE
};
#endif

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;
}

это не должно работать в C++:

Days.Saturday

Days - это не область или объект, содержащий элементы, к которым можно получить доступ с помощью оператора dot. Этот синтаксис является просто C# - ism и не является законным в C++.

Microsoft уже давно поддерживает расширение C++, которое позволяет получить доступ к идентификаторам с помощью оператора scope:

enum E { A, B, C };

A;
E::B; // works with Microsoft's extension

но это нестандартно перед C++11. В C++03 идентификаторы, объявленные в перечислении, существуют только в той же области, что и тип перечисления себя.

A;
E::B; // error in C++03

C++11 позволяет квалифицировать идентификаторы перечисления с именем перечисления, а также вводит классы перечисления, которые создают новую область для идентификаторов вместо размещения их в окружающей области.

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

enum class F { A, B, C };

A; // error
F::B;

к сожалению, элементы перечисления являются "глобальными". Вы получаете доступ к ним, делая day = Saturday. Это означает, что вы не можете иметь enum A { a, b } ; и enum B { b, a } ; ибо они находятся в конфликте.

перечисления в C++ похожи на целые числа, замаскированные именами, которые вы им даете, когда вы объявляете свои значения перечисления (это не определение, а только подсказка, как это работает).

но в вашем коде есть две ошибки:

  1. заклинание enum все в нижнем регистре
  2. вам не нужно Days. до субботы.
  3. если это перечисление объявлено в классе, то используйте if (day == YourClass::Saturday){}

Если вы все еще используете 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)  ...

вы ищете Строго Типизированные Перечисления, функция доступна в C++11 стандартные. Он превращает перечисления в классы со значениями области.

используя свой собственный пример кода :

  enum 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 

используя :: как методы доступа к перечислениям не удастся, если целевой стандарт C++ до C++11. Но некоторые старые компиляторы не поддерживают его, а некоторые IDE просто переопределяют эту опцию и устанавливают старый C++ std.

Если вы используете gcc, включите C+11 с - std=c++11 или - std=gnu11 .

будьте счастливы !

Я думаю, что ваша корневая проблема заключается в использовании . вместо ::, который будет использовать пространства имен.

попробуй:

enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Days::Saturday;
if(Days::Saturday == day)  // I like literals before variables :)
{
    std::cout<<"Ok its Saturday";
}

прежде всего, сделайте 'E' в перечислении, 'e' в нижнем регистре.

во-вторых, падение типа имя "дней" в " Дней.Суббота'.

третье ...купите себе хорошую книгу на C++.

Comments

    Ничего не найдено.