The new c++ 11 standard introduces a new kind of enum called strongly typed enum. The new kwyword is ‘enum class’ . What is difference between ‘enum’ and ‘enum class’? According to this proposal http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf the traditional c++ enum has three problems

  • The tradition old-style enum do not have their own scope

#include<stdio.h>
#include<iostream>

enum tech { man , machine, algorithm };
enum book { manual , machine, learn_algorithm };

int main()
{
  return 0;
}

Try to compile the above code and see the output, the output would be as follows:

“enumc.cpp:4:22: error: redeclaration of ‘machine’
 enum book { manual , machine, learn_algorithm };
                      ^
enumc.cpp:3:19: note: previous declaration ‘tech machine’
 enum tech { man , machine, algorithm };
                   “

Note: the enumerators of an enum are exported to the scope in which the enum is defined.

Solution in c++ 11 for above problem: use ‘enum class’ instead of using old enum

#include<stdio.h>

enum class tech { man , machine, algorithm };
enum class book { manual , machine, learn_algorithm };

int main()
{
  return 0;
}

compile :

g++ -std=c++11 sample.cpp

  • Current (old ) C++ enum are not type-safe

The values of enumerators implicitly convert to int in old c++ standard. Let us see below code

#include<iostream>
using namespace std;

enum Animal { Dog,Cat,Mouse };

int main()
{
  int a = Cat; // enum Cat is promoted to int
              // implicitly 
  return 0;
}

If you want to prevent implicit conversion to int for enum then we need to replace enum keyword with c++ 11 new keyword ‘enum class’

#include<iostream>
using namespace std;

enum class Animal { Dog,Cat,Mouse };

int main()
{
  int a = Cat; // enum Cat is promoted to int
              // implicitly error
  return 0;
}

Compile:

#g++ -std=c++11 sample.cpp

Output:

8:11: error: ‘Cat’ was not declared in this scope
   int a = Cat; // enum Cat is promoted to int
  • The Underlying Type

c++ standard says The underlying type of an enumeration is an integral type that can represent all the enumerator values defined in the enumeration. It is implementation-defined which integral type is used as the underlying type for an enumeration except that the underlying type shall not be larger than int unless the value of an enumerator cannot fit in an int or unsigned int. If the enumerator-list is empty, the underlying type is as if the enumeration had a single enumerator with value 0. The value of sizeof() applied to an enumeration type, an object of enumeration type, or an enumerator, is the value of sizeof() applied to the underlying type.”

By default, the underlying type of an enumeration is int. However, you can specify the type to be signed or unsigned forms of int, short, long, __int32, or __int64. You can also use char.

#include <limits>
using namespace std;

enum Animal : char 
{
  Dog,
  Cat,
  Mouse
};

int main()
{
  return 0;
}

when we compile the above program without using c++ 11 , we will get error or warning as below

num1.cpp:6:15: warning: scoped enums only available with -std=c++11 or -std=gnu++11

enum Animal : char

what are advantage of using enum class Strongly typed Enum?

Forward declaration of an enum in c++ is not possible in old c++.

The reason the enum can’t be forward declared is that without knowing the values, the compiler can’t know the storage required for the enum variable. C++ Compiler’s are allowed to specify the actual storage space based on the size necessary to contain all the values specified. If all that is visible is the forward declaration, the translation unit can’t know what storage size will have been chosen – it could be a char or an int, or something else.

#include<iostream>
using namespace std;

// forward declaration 
enum Animal; 

void foo( Animal obj )
{

}
int main()
{
  return 0;
}

The above code will give error  if we compile the code using g++ sample.cpp

sample.cpp:5:6: error: use of enum ‘Animal’ without previous declaration
 enum Animal;
      ^
sample.cpp:7:11: error: variable or field ‘foo’ declared void
 void foo( Animal obj )
           ^
sample.cpp:7:11: error: ‘Animal’ was not declared in this scope

we can use ‘enum class’ in plave of enum and can compile using g++ -std=c++11 sample.cpp

#include<iostream>
using namespace std;

// forward declaration
enum class Animal;

void foo( Animal obj )
{

}
int main()
{
  return 0;
}

Ref:

https://stackoverflow.com/questions/71416/forward-declaring-an-enum-in-c



Related Contents to follow