Предположим, у нас есть что-то 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)
?
Что эти два на самом деле ссылаются, в том, что один в порядке, а другой вызывает ошибку компиляции?
Ответы:
Этот код неверен:
Потому что
Days
это не сфера и не объект. Это тип. И сами типы не имеют членов. То, что вы написали, эквивалентноstd::string.clear
.std::string
это тип, поэтому вы не можете использовать.
его. Вы используете.
на экземпляре класса.К сожалению, перечисления являются волшебными, и аналогия на этом заканчивается. Потому что с классом вы можете сделать,
std::string::clear
чтобы получить указатель на функцию-член, но в C ++ 03,Days::Sunday
является недействительным. (Что грустно). Это потому, что C ++ (в некоторой степени) обратно совместим с C, а C не имеет пространств имен, поэтому перечисления должны были находиться в глобальном пространстве имен. Таким образом, синтаксис просто:К счастью, Майк Сеймур отмечает, что это было решено в C ++ 11. Измените
enum
наenum class
и получите свою собственную область; этоDays::Sunday
не только допустимо, но и является единственным способом доступаSunday
. Счастливые дни!источник
enum
наenum class
и получите свою собственную область; этоDays::Sunday
не только допустимо, но и является единственным способом доступаSunday
. Счастливые дни!'.' token
иdot operator
, кроме того, что это токен, а не оператор, и он показывает точный символ, а не имя.enum
, вы не можете использовать ни область, ни глобальную область (::Saturday
). Если у вас естьenum class
(что совсем другое), то вы должны использоватьDays::Saturday
.Этого будет достаточно, чтобы объявить переменную enum и сравнить ее:
источник
Days
это не сфера и не объект. Это тип. И сами типы не имеют членов.std::string.clear
также не компилируется по той же причине.enum class
, которые находятся в области действия (впервые в 2011 г.) имеют собственную область видимости и доступны с помощью оператора области видимостиDays::Saturday
. Оператор доступа к членам (.
) используется только для доступа к членам класса.Многое из этого должно дать вам ошибки компиляции.
Теперь
Saturday
,Sunday
и т.д. могут быть использованы в качестве голых констант верхнего уровня, иDays
может быть использован в качестве типа:И аналогично позже, чтобы проверить:
Эти
enum
значения , как голые константы - они ип -scoped - с небольшой дополнительной помощи со стороны компилятора: (если вы не используете ++ 11 C классов перечислений ) , они не инкапсулированы как объекта или структуры элементов , например, и вы не можете обратиться к ним в качестве членов вDays
.Вы получите то, что ищете, с C ++ 11 , который представляет
enum class
:Обратите внимание, что этот C ++ немного отличается от C в двух отношениях, во-первых, C требует
enum
объявления ключевого слова при объявлении переменной:источник
Вы можете использовать трюк для использования областей по своему усмотрению, просто объявите enum следующим образом:
источник
Вместо того, чтобы использовать кучу операторов if, перечисления хорошо подходят для переключения операторов
В построителе уровней, которые я строю для своей игры, я использую несколько комбинаций enum / switch.
РЕДАКТИРОВАТЬ: Еще одна вещь, я вижу, вы хотите синтаксис похож на;
Вы можете сделать это в C ++:
Вот очень простой пример:
EnumAppState.h
Somefile.cpp
источник
Если вы все еще используете C ++ 03 и хотите использовать перечисления, вам следует использовать перечисления внутри пространства имен. Например:
Вы можете использовать enum вне пространства имен, например,
источник
Вы ищете строго типизированные перечисления , функция, доступная в стандарте C ++ 11 . Превращает перечисления в классы со значениями области видимости.
Используя ваш собственный пример кода, это:
Использование в
::
качестве средств доступа к перечислениям не удастся, если нацелено на стандарт C ++ до C ++ 11. Но некоторые старые компиляторы не поддерживают его, а некоторые IDE просто переопределяют эту опцию и устанавливают старый стандарт C ++.Если вы используете GCC, включите C + 11 с -std = c ++ 11 или -std = gnu11 .
Будь счастлив!
источник
enum class Days { ...
.Это не должно работать в C ++:
Days не является областью или объектом, который содержит членов, к которым вы можете получить доступ с помощью оператора точка. Этот синтаксис является просто C # -измом и недопустим в C ++.
Microsoft уже давно поддерживает расширение C ++, которое позволяет вам получать доступ к идентификаторам, используя оператор области действия:
Но это нестандартно до C ++ 11. В C ++ 03 идентификаторы, объявленные в enum, существуют только в той же области видимости, что и сам тип enum.
C ++ 11 делает законным квалифицировать идентификаторы перечисления с именем перечисления, а также вводит классы перечисления, которые создают новую область видимости для идентификаторов вместо того, чтобы помещать их в окружающую область видимости.
источник
К сожалению, элементы перечисления являются «глобальными». Вы получаете доступ к ним, делая
day = Saturday
. Это означает, что вы не можете иметь,enum A { a, b } ;
иenum B { b, a } ;
они находятся в конфликте.источник
enum class
в C ++ 11, то есть. Перед этим вы должны сделать фиктивные занятия.Хотя C ++ (исключая C ++ 11) имеет перечисления, значения в них «просочились» в глобальное пространство имен.
Если вы не хотите, чтобы они просочились (и не НУЖНО использовать тип enum), подумайте о следующем:
источник
Перечисления в C ++ похожи на целые числа, маскируемые именами, которые вы даете им, когда вы объявляете свои значения перечислений (это не определение, а лишь подсказка, как это работает).
Но в вашем коде есть две ошибки:
enum
все строчныеDays.
до субботы.if (day == YourClass::Saturday){}
источник
Я думаю, что вашей основной проблемой является использование
.
вместо::
, которое будет использовать пространство имен.Пытаться:
источник
Days::
область, как в вашем примере, вы должны определить перечислениеenum class Days
и использовать расширение C ++ 03 + Microsoft или C ++ 11.-std=c++98
или-std=c++03
. Лязг вполне понятноwarning: use of enumeration in a nested name specifier is a C++11 extension
.Если мы хотим строгой безопасности типов и ограниченного перечисления, использование
enum class
хорошо в C ++ 11.Если нам приходилось работать в C ++ 98, мы могли бы воспользоваться советом
InitializeSahib
,San
данным для включения enum в области видимости.Если мы также хотим строгой безопасности типов, следующий код может реализовать что-то вроде
enum
.Код изменен из примера класса Месяц в книге Эффективное C ++ 3-е: Пункт 18
источник
Прежде всего, сделайте «E» в enum, «e» в нижнем регистре.
Во-вторых, добавьте имя типа «Дни» в «Days.Saturday».
В-третьих ... купите себе хорошую книгу по С ++.
источник