How to Use Enums in C++

How to define an enumerated type (enum) in C?

Declaring an enum variable is done like this:

enum strategy {RANDOM, IMMEDIATE, SEARCH};
enum strategy my_strategy = IMMEDIATE;

However, you can use a typedef to shorten the variable declarations, like so:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy my_strategy = IMMEDIATE;

Having a naming convention to distinguish between types and variables is a good idea:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type;
strategy_type my_strategy = IMMEDIATE;

What is the use of enums in C and C++

Advantages over macros

  • Debuggers can print names for values
  • Your constants will be scoped (if you want, you can put them also in a namespace in C++)
  • The compiler can warn if you forget an enum constant in a switch
  • Values for the constants are automatically assigned, if you don't give explicit values
  • The enum type is always large enough to hold all the constants. When using #define, you have to commit to int or some typedef and ensure that all the constants fit manually

How to use enum in C

Your struct typedef is basically saying "If I had a "status" field in my record, it could have the value "call" or the value "wait". The warning is basically saying "you never allocated a field".

Possible change:

enum status {CALL, WAIT};

typedef struct restaurant
{
char name[30];
int groupSize;
enum status my_status;
struct restaurant *nextNode;
}list;

Here's more info:

  • How to define an enumerated type (enum) in C?

How to use enums in C++

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!

Using enum members with enum name in C

enum is a list of values, an "enumeration". It is not a struct/container class with members.

Now what you should do for clarity is to only compare enumeration constants of a given type with variables of the same type. Not against uint8_t as in your example.

This is pretty much self-documenting code:

void do_work (BOARD_TYPE board_type) {
if (board_type == F164) {
// Do stuff...
}
}

Good compilers can be configured to give warnings when comparing enums against wrong types. Otherwise you can also create type safe enums with some tricks.

You can also prefix all enum constants to indicate what type they belong to - this is common practice:

typedef enum {
BOARD_F105 = 0x00,
BOARD_F164 = 0x10,
BOARD_F193 = 0x20,
BOARD_F226 = 0x30,
BOARD_F227 = 0x40
}BOARD_TYPE;

How to use enums as flags in C++?

The "correct" way is to define bit operators for the enum, as:

enum AnimalFlags
{
HasClaws = 1,
CanFly = 2,
EatsFish = 4,
Endangered = 8
};

inline AnimalFlags operator|(AnimalFlags a, AnimalFlags b)
{
return static_cast<AnimalFlags>(static_cast<int>(a) | static_cast<int>(b));
}

Etc. rest of the bit operators. Modify as needed if the enum range exceeds int range.



Related Topics



Leave a reply



Submit