Как использовать перечисления в 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)
?
что эти два на самом деле относятся, в том, что один в порядке, и один вызывает ошибку компиляции?
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 }; #endifSomefile.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.SaturdayDays - это не область или объект, содержащий элементы, к которым можно получить доступ с помощью оператора 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++03C++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++ похожи на целые числа, замаскированные именами, которые вы им даете, когда вы объявляете свои значения перечисления (это не определение, а только подсказка, как это работает).
но в вашем коде есть две ошибки:
- заклинание
enumвсе в нижнем регистре- вам не нужно
Days.до субботы.- если это перечисление объявлено в классе, то используйте
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