Как использовать перечисления в С++
Предположим, что enum
имеет следующий вид:
enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
Я хочу создать экземпляр этого enum
и инициализировать его с помощью правильного значения, поэтому я:
Days day = Days.Saturday;
Теперь я хочу проверить свою переменную или экземпляр с существующим значением enum
, поэтому я:
if (day == Days.Saturday)
{
std::cout<<"Ok its Saturday";
}
Что дает мне ошибку компиляции:
error: ожидаемое первичное выражение перед '. Маркер
Чтобы было ясно, в чем разница между высказыванием:
if (day == Days.Saturday) //Causes compilation error
и
if (day == Saturday)
?
На что эти два на самом деле ссылаются, в том, что один ОК, и один вызывает ошибку компиляции?
Ответы
Ответ 1
Этот код неверен:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Days.Saturday;
if (day == Days.Saturday)
Потому что 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)
К счастью, Майк Сеймур отмечает, что это было рассмотрено в C++ 11. Измените enum
на enum class
и он получит собственную область видимости; поэтому Days::Sunday
не только действителен, но и является единственным способом доступа к Sunday
. Счастливые дни!
Ответ 2
Этого будет достаточно, чтобы объявить переменную enum и сравнить ее:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Saturday;
if (day == Saturday) {
std::cout << "Ok its Saturday";
}
Ответ 3
В значительной степени это должно привести к ошибкам компиляции.
// 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
похожи на голые константы - они не ограничены областью - с небольшой дополнительной помощью от компилятора: (если вы не используете классы переполнения С++ 11), они не инкапсулируются как объект или например, члены структуры, и вы не можете ссылаться на них как на членов Days
.
У вас будет то, что вы ищете, С++ 11, в котором вводится enum class
:
enum class Days
{
SUNDAY,
MONDAY,
// ... etc.
}
// ...
if (day == Days::SUNDAY)
// ...
Обратите внимание, что этот С++ немного отличается от C несколькими способами: один из них - это использование ключевого слова enum
при объявлении переменной:
// day declaration in C:
enum Days day = Saturday;
Ответ 4
Вы можете использовать трюк для использования областей, как хотите, просто объявите перечисление таким образом:
struct Days
{
enum type
{
Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday
};
};
Days::type day = Days::Saturday;
if (day == Days::Saturday)
Ответ 5
Вместо того, чтобы использовать кучу if-операторов, перечисления хорошо подходят для переключения операторов
Я использую некоторые комбинации enum/switch в построителе уровней, который я создаю для своей игры.
EDIT: Другое дело, я вижу, что вам нужен синтаксис, похожий на;
if(day == Days.Saturday)
etc
Вы можете сделать это в С++:
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;
}
Ответ 6
Это не должно работать на С++:
Days.Saturday
Дни - это не область или объект, который содержит членов, к которым вы можете получить доступ с помощью оператора точки. Этот синтаксис является просто С# -ism и не является законным в С++.
Корпорация Майкрософт уже давно поддерживает расширение С++, которое позволяет вам обращаться к идентификаторам с помощью оператора области:
enum E { A, B, C };
A;
E::B; // works with Microsoft extension
Но это нестандартно перед С++ 11. В С++ 03 идентификаторы, объявленные в перечислении, существуют только в той же области, что и сам тип перечисления.
A;
E::B; // error in C++03
С++ 11 разрешает квалифицировать идентификаторы перечислений с именем перечисления, а также вводит классы перечисления, которые создают новую область для идентификаторов вместо размещения их в окружении.
A;
E::B; // legal in C++11
enum class F { A, B, C };
A; // error
F::B;
Ответ 7
Если вы все еще используете С++ 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";
}
Ответ 8
Перечисления в С++ похожи на целые числа, замаскированные именами, которые вы им даете, когда вы объявляете свои значения enum (это не определение, а только подсказка, как это работает).
Но в вашем коде есть две ошибки:
- Заклинание
enum
все строчные буквы
- Вам не нужно
Days.
до субботы.
- Если это перечисление объявлено в классе, используйте
if (day == YourClass::Saturday){}
Ответ 9
К сожалению, элементы перечисления являются "глобальными". Вы обращаетесь к ним, выполняя day = Saturday
. Это означает, что у вас не может быть enum A { a, b } ;
и enum B { b, a } ;
, поскольку они находятся в конфликте.
Ответ 10
В то время как С++ (исключая С++ 11) имеет перечисления, значения в них "просачиваются" в глобальное пространство имен.
Если вы не хотите, чтобы они просочились (и НЕ НУЖНО использовать тип перечисления), рассмотрите следующее:
class EnumName {
public:
static int EnumVal1;
(more definitions)
};
EnumName::EnumVal1 = {value};
if ([your value] == EnumName::EnumVal1) ...
Ответ 11
Вы ищете строго типизированные перечисления, функция, доступная в стандарте 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
Использование ::
качестве средств доступа к перечислениям потерпит неудачу, если нацелен на стандарт C++ до C++ 11. Но некоторые старые компиляторы не поддерживают его, а некоторые IDE просто отменяют эту опцию и устанавливают старый C++ стандарт.
Если вы используете gcc, включите C + 11 с -std = C++ 11 или -std = gnu11.
Будь счастлив !
Ответ 12
Я думаю, что ваша корневая проблема заключается в использовании .
вместо ::
, который будет использовать пространство имен.
Try:
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";
}
Ответ 13
Прежде всего, сделайте 'E' в перечислении, 'e' в нижнем регистре.
Во-вторых, отмените имя типа "Дни" в "Дни. Суббота".
В-третьих... купите себе хорошую книгу на С++.