C++11 enum : scoped enumeration


C++11 enum scoped enumeration

C++11 introduced a new type of enumeration known as scoped enumeration.This type of enumeration is also known as strong enumeration or classes enumeration because it require mentioning of ‘struct’ or ‘class’ explicitly before the enumeration name.It has lots of advantage over the C type enumeration.In fact scoped enumeration was introduced to fill the gap of the C type enumeration.In this post we will discuss all the properties exhibited by scoped enumeration.

Link:C type enum: unscoped enumeration

Property 1:Scoped enumeration syntax

While defining scoped enumeration it is required that we mentioned the keyword ‘class‘ or ‘struct‘ to signify that the enumeration is a scoped enum type.If we look at the C type enum the keyword ‘class’ or ‘struct’ is not required.This is one of the changes made in scoped enumeration.

enum Value { val 1, val2 } ; //C type enum

enum class New_value { nval1 , nval2 }; ///scoped enumeration

enum struct Size { size ,max_size } ;///scoped enumeration





property 2:Using scope resolution operator to access the enumerators

In C type enum we can directly access the enumerators of the enum by just using their name.But in scoped enumeration we require scope resolution(::) operator to use the enumerators.

enum Value{ val }; ///unscoped enum

enum class Int { i1 }; //scoped enum

int main( )
{
Value val1=val ; ///ok ,unscoped enum

Int i2=i1 ; ///error

Int i2=Int::it ; ///work fine,note the scope resolution operator

return 0 ;
}

The scope resolution operator binds the enum name and the enumerator name.


Property 3:Defining the enumerators type explicitly

In scoped enumeration we can explicitly define the underlying type of the enum class.This means we can define the type of the enumerators explicitly.To do this we use the colon(:) sign and append the data type to the enum name.Consider the code below.

enum class Int:int { i1, i2 }; //i1 ,i2 is int type

enum class Char:char { c1 ,c2 }; ///c1 and c2 is char type

Defining the enumerators type explicitly to one type doesn’t mean the enumerators can hold the literals of that type.They can hold only constant integer value.Also note we cannot make the underlying type a floating point type or a string type.

enum class Int:int { i1=90 , i2=78 }; //work fine

enum class Char:char { c1=’C’ , c2=’L’ } ; //ok ,character literal converted to int type

enum class Float_data:float { f1=90.67 } ;//error,underlying type is not const int type

enum class String:string { s1 } ;///error,underlying type cannot be string type

So how does making the underlying type explicitly point to one type affect the enum class or the enumerators? When we define the underlying type explicitly we are making the size of the enumerators have the size of the type mentioned.By default the enumerators will have the size of int type.But if we define the enumerators type as say a char type then the enumerators will have a size of the char type i.e. 1 byte.So defining the type explicitly affect the size of the enumerators.

enum class Int:int { i1 } ;

enum class Long:long long { l1,l2 } ;

enum class Char:char {c1,c2 } ;

cout<< sizeof( Int::i1 ) ; ///give 4
cout<< sizeof(Long::l1 ) ; ///gives 8
cout << sizeof( Char::c1 ) ; ///gives 1

Since the size of enumerators is limited by the type explicitly mentioned, the range of values the enumerators can hold is also limited to the size of the type.For instance in the enum class having it’s underlying type as char type,the enumerators cannot hold the value 128 or any value greater then 128,because 128 cannot be represented by 7 bits binary digit -the left most bit is reserve for the ‘+‘ or ‘‘ sign.

enum class Char:char {c1 =128 , ///error too large for char type
c2=127 } ; ///work fine

enum class Unsigned_char:unsigned char {c1 =255 , ///work fine
c2=256 } ; ///error too large for unsigned char type enumerator

Link:Difference between char ,signed char and unsigned char type.


 


Stop wasting time,earn money($$$) from your website-Join Now!

Property 4:enumerators can have same name

In C type enum we cannot make the name of the enumerators of different enumeration have the same name.But in scoped enumeration we can.

enum Value { val} ;
enum New { val } ; //error,val already used in Value enum

enum class Size { max_size } ; //work fine
enum class Int { max_size } ; //work fine

Compiler permits only the enumerators to have same name,we cannot make the name of the enumeration class similar.

enum class data_size { ds };

enum data_size{ d1 } ;//error ,same name as the above enum


Property 5:Cannot implicitly convert to and from int type

The C type enumeration allows implicit conversion of enumerators to int type .This means we can assign enumerators value to int type variable.But in scoped enumeration implicit conversion to and from int is not allowed.Consider the code below.

enum Value { val} ;

enum class Int:int {i1 , i=89 , i3 } ;

int main( )
{
int i=val ; ///work fine ,val converted to int type

const int i4=Int::i1 ; //error ,i1 cannot be converted to int type

return 0 ;
}

The scoped enumeration is more cautious of how the enumerators are used,and so implicit conversion it not allowed.

Implicit conversion to and from int is not allowed so how do we use the enumerators in our program,the next section explains it.


 


Property 6::How to use the enumerators value

Suppose we want to use the enumerators of scoped enumeration to perform certain operations.Say you want to assign the enumerators value to another int variable.In such case the only way that will allows us to achieve the task is to cast the enumerators to int type first.In ‘property 5’ we have seen that implicit conversion to and from int is not allowed so,we will perform explicit casting using static_cast.

Link: what is static_cast?

enum class Int:int{i1=90, i2=89 };

int val=static_cast<int>(Int::i1) ; //work fine

cout<< val ;

And one other thing that scoped enumeration does not allowed is outputting the enumerators value to the console screen.In such case also performing static_cast on the enumerator will solve the problem.

enum class Int:int{ i1=90 , i2=89 } ;

cout<< Int::i1 ; ///error

cout<< static_cast<int>(Int::i1) ; ///work fine


Property 7 :forward declaration with scoped enumeration is allowed

The scoped enumeration allow forward declaration of enum classes.The term ‘forward declaration‘ refer to declaration of enumeration class without the enumerators.In C type forward declaration is allowed but we must define the underlying type of the enumeration explicitly.In scoped enumeration we need not explicitly define the type to forward declare the enum class because the underlying type will be implicitly declare as int type;the compiler does this for us.

enum Value ; ///error , C type enum and underlying type is missing

enum Value:int ; ///work fine ,type is mentioned

enum class data_size ; ///work fine,mentioning of type not required


Conclusion

The enumeration can be declared as a member of a class.Sometimes when we require a ‘const int’ type member in a class and instead of using the normal ‘const int’ variable we can use the enum.And thus the enumerators will act as a constant data member.