Enumerations in C++ | C++ Enum

The C++ programming language offers various useful features and functionalities to the programmers. You will get great advantage while using the C++ programming language. In this tutorial, we are going to teach you about Enumerations in C++ (C++ Enum) in detail.

What is Enumeration in C++?

To put it short, enumeration is a user-defined data type and it consists of fixed and constant values. A programmer defines these values during declaring the enumerated type.

For example, you can use it for the day within a week or for directions etc.
Syntax:-

enum Name_enumerated_type{data1,data2,....,dataN};

enum keyword is used to define an enumeration. After defining enumerated types, variables are created. You can create it in two ways:-

1. First, you can declare it while declaring enumerated types.

2. Second, you can create enumerated type variables like the normal variables.

Name_enumerated_type name_of_variable = value;

Example:-

enum Week{Mon,Tue,Sun};

Above, Week is the name of the enumeration. And Mon, Tue, Sun are values of type Week. You can also change the value of an enum element while declaring:-

enum Week{
Mon=1,
Tue=2,
Sun=3
};

Enumerated Type Declaration in C++

Before using it, you have to create variables of enum type:-

enum bool{True,False};
// within function
enum bool checking;

Above, checking is a variable of type enum bool which is created. You can also write the above one in another way:-

enum bool{
True,False
}checking;

Example:- Simple Enumeration Type in C++

#include <iostream>
using namespace std;

enum Week { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };

int main()
{
  Week day;
  day = Saturday;
  cout << "Day: " << day+1;
  return 0;
}

Output:-

Day: 7

Example:- Changing values of enum in C++

#include <iostream>
using namespace std;

enum directions{ north=23, south=21, west=2, east=5};

int main() {

  directions d;

  d = west;
  cout << "West: " << d << endl;

  return 0;
}

Output:-

West: 2

Why to use enums in C++?

From many possible values, an enum variable only takes one value. Below is an example on why to use enums:-

#include <iostream>
using namespace std;

enum treat{
  pasta=40,
  pizza=200,
  spaghetti=65
} food;

int main()
{
  food = pizza;
  cout << "Enum variable's size: " << sizeof(food) << " bytes!";   
  return 0;
}

Output:-

Enum variable’s size: 4 bytes!

Size of an integer is 4 bytes. That’s why the output of the above program is 4 bytes. Using enum, you can easily work with flags. While using enum, you will get efficiency along with flexibility.

Important points to remember for C++ enum

  • You can easily use enum in switch
  • You can also traverse enums
  • With the help of enum, you can improve type safety
  • Enum can have fields, constructors and methods

Using enums for flags

Let’s take an example:-

enum design{
    Bold = 2,
    Underline = 4
}click;

Let’s say, to work with text on windows applications, you are creating a button. And you can set flags Bold and Underline. The integral constants are power of 2. Using bitwise OR(|) operator, you can also add two or more flags at once without overlapping. With that, you can choose two or more flags at once.

For Example:-

#include <iostream>
using namespace std;
enum design{
  Bold = 5,
  Underline = 2
};
int main()
{
  int create = Bold | Underline;
  cout << create;
  return 0;
}

Output:-

7

Above, the output is 7. So, you can say that bold and underline are used.

C++ Enumerator Scope

The enumerator name must be qualified by the enum type name in scoped enums. In C or C++, the unqualified enums are visible throughout the scope in which the enum is declared.

Below is an example of the basic difference between two kinds of enums:-

namespace Scoped_game
{
  enum class Cards Diamonds, Hearts, Clubs, Spades };

  void Play(Cards card)
  {
    	if (card == Cards::Spades) 
    	{ /*...*/}
  }
}

namespace NonScoped_game
{
  enum Cards{ Diamonds, Hearts, Clubs, Spades };

  void Play(Cards card)
  {
    	if (card == Clubs) 
    	{ /*...*/
    	}
  }
}

Every enumerator must have a unique name and is always treated as a constant within the scope where enum is defined or within the enum itself. There is no need to give unique names to the values.

Enums with no enumerators

You can define an enum with an explicit underlying type and no enumerators. With that, you can introduce a new integral type that has no implicit conversion to any other data type.
You can also avoid the potential for subtle errors caused by implicit conversions.

enum class byte : unsigned char { };

Below is an example on how to initialize enums with no enumerators:-

enum class byte : unsigned char { };

enum class T : int { };
T t1{ 0 };
T t2 = T{ 0 };

struct A
{
  T t{ 0 };
  A() : t{ 0 } { }
};

T* ptr = new T{ 0 };

void fun(T t) {};

int main()
{
  fun(T{ 0 });
  byte i{ 42 };
  byte j = byte{ 42 };

  return 0;
}

Unscoped Enumeration

With scoped enumerators, you cannot implicitly convert to their underlying type. You cannot use a scoped enumeration when you are thinking to implicitly convert the enum values to their underlying type.

enum Bob{ a, c = 10, f, g = f + c };
//a = 0, c = 10, f = 2, g = 12

The values of the unscoped enumeration type are implicitly convertible to integral types. You can convert the values to their underlying type if the underlying type is fixed.

With the help of unscoped enums, you can replace #define Bob 43 style macros. Instead of a token, here is a token that has the same meaning. Scoped enumeration prevents accidental conversion to the underlying type.

Summary

In this tutorial, we discussed enumeration in C++, declaration of enumerated types and why you should use enums in C++. We discussed how you can use enums for flags.