How to use enums in C++
Suppose we have an enum
like the following:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
I want to create an instance of this enum
and initialize it with a proper value, so I do:
Days day = Days.Saturday;
Now I want to check my variable or instance with an existing enum
value, so I do:
if (day == Days.Saturday)
{
std::cout << "Ok its Saturday";
}
Which gives me a compilation error:
error: expected primary-expression before ‘.’ token
So to be clear, what is the difference between saying:
if (day == Days.Saturday) // Causes compilation error
and
if (day == Saturday)
?
What do these two actually refer to, in that one is OK and one causes a compilation error?
This code is wrong:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Days.Saturday;
if (day == Days.Saturday)
Because Days
is not a scope, nor object. It is a type. And Types themselves don't have members. What you wrote is the equivalent to std::string.clear
. std::string
is a type, so you can't use .
on it. You use .
on an instance of a class.
Unfortunately, enums are magical and so the analogy stops there. Because with a class, you can do std::string::clear
to get a pointer to the member function, but in C++03, Days::Sunday
is invalid. (Which is sad). This is because C++ is (somewhat) backwards compatable with C, and C had no namespaces, so enumerations had to be in the global namespace. So the syntax is simply:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Saturday;
if (day == Saturday)
Fortunately, Mike Seymour observes that this has been addressed in C++11. Change enum
to enum class
and it gets its own scope; so Days::Sunday
is not only valid, but is the only way to access Sunday
. Happy days!
This will be sufficient to declare your enum variable and compare it:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Saturday;
if (day == Saturday) {
std::cout << "Ok its Saturday";
}
Much of this should give you compilation errors.
// note the lower case enum keyword
enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };
Now, Saturday
, Sunday
, etc. can be used as top-level bare constants,and Days
can be used as a type:
Days day = Saturday; // Days.Saturday is an error
And similarly later, to test:
if (day == Saturday)
// ...
These enum
values are like bare constants - they're un-scoped - with a little extra help from the compiler: (unless you're using C++11 enum classes) they aren't encapsulated like object or structure members for instance, and you can't refer to them as members of Days
.
You'll have what you're looking for with C++11, which introduces an enum class
:
enum class Days
{
SUNDAY,
MONDAY,
// ... etc.
}
// ...
if (day == Days::SUNDAY)
// ...
Note that this C++ is a little different from C in a couple of ways, one is that C requires the use of the enum
keyword when declaring a variable:
// day declaration in C:
enum Days day = Saturday;
You can use a trick to use scopes as you wish, just declare enum in such way:
struct Days
{
enum type
{
Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday
};
};
Days::type day = Days::Saturday;
if (day == Days::Saturday)