Strongly-Typed Enums

Contents[Show]

Enumerations are a convenient way to define integer constants with names. This integer constants are called enumerators. Sadly, classical enums have a few drawbacks.

The drawbacks of enumerations in classical C++

 A short reminder. Three drawbacks of enumerations.

  1. The enumerators implicitly convert to int.
  2. They introduce the enumerators in the enclosing scope.
  3. The type of the enumeration can not be specified.

At first to the point 3. Enumerations can not be forward declared because their type is not known. There is only the guarantee for the enumerators in classical C++.The type must be integral and big enough to hold the enumerators.

Point 1 and point 2 are more surprising.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// enumClassic.cpp

#include <iostream>

int main(){
	
  std::cout << std::endl;
	
  enum Colour{red= 0,green= 2,blue};
  
  std::cout << "red: " << red << std::endl;
  std::cout << "green: " << green << std::endl;
  std::cout << "blue: " << blue << std::endl;
  
  int red2= red;
  
  std::cout << "red2: " << red2 << std::endl;
  
  // int red= 5;  ERROR
  
}

On the one hand are the enumerators red, green, and blue know in the enclosing scope. Therefore, the definition of the variable red in line 19 is not possible. On the other hand red can be implicitly converted to int.

enumClassic

If you use no name for an enumeration like enum{red, green, blue},  the enumerators will be introduced in the enclosing scope.

But that surprise ends with C++11.

Strongly-typed enumerations

The strongly-typed enumerations have to follow stronger rules:

  1. The enumerators can only be accessed in the scope of the enumeration.
  2. The enumerators don't implicitly convert to int.
  3. The enumerators aren't imported in the enclosing scope.
  4. The type of the enumerators is by default int. Therefore, you can forward the enumeration.

The syntactical difference between the classic enumerations and the strongly-typed enumerations is minimal. The strongly-typed enumerations additionally get the keyword class or struct.

enumClassicStrongEng

If you want to use an enumerator as an int, you have to explicitly convert it with static_cast.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// enumCast.cpp

#include <iostream>

enum OldEnum{
  one= 1,
  ten=10,
  hundred=100,
  thousand= 1000
};

enum struct NewEnum{
  one= 1,
  ten=10,
  hundred=100,
  thousand= 1000
};

int main(){
	
  std::cout << std::endl;

  std::cout << "C++11= " << 2*thousand + 0*hundred + 1*ten + 1*one << std::endl;
  std::cout << "C++11= " << 2*static_cast<int>(NewEnum::thousand) + 
                            0*static_cast<int>(NewEnum::hundred) + 
                            1*static_cast<int>(NewEnum::ten) + 
	                    1*static_cast<int>(NewEnum::one) << std::endl;

}

 

In order to calculate or output the enumerators, you have to convert them into integral types. Either the addition nor the output of strongly-typed enumerations is defined. 

enumCast 

 

I often speak in this post about classical versus strongly-typed enumerations. Often there are called scoped and unscoped enumerations.

Explicitly specifying the type

I ignored one feature of the enumerations in C++11. You can explicitly specify the type of the enumerators. By default, it's int.

But that does not have to be. You can use integral types like bool, char, short int, long int, or, long long int.  Read msdn.microsoft.com for the details. You can read in my post Check types how you can check at compile time if a type is integral. 

You can independently use the scoped property and the explicit type specification of an enumeration. Dependent on the base types the enumerations have different size.

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// enumType.cpp

#include <iostream>
#include <climits>

enum struct Colour0: bool{
  red,     // 0
  blue     // 1
};

enum Colour1{
  red= -5,   
  blue,      // -4
  green      // -3
};

enum struct Colour2: char{
  red= 100,
  blue, // 101
  green // 102
};

enum class Colour3: long long int{
  //red= 	std::numeric_limits<long long int>::min();
  red= LLONG_MIN,
  blue,    // std::numeric_limits<long long int>::min() + 1
  green    // std::numeric_limits<long long int>::min() + 2
};

int main(){

  std::cout << std::endl;

  std::cout << "sizeof(Colour0)= "  << sizeof(Colour0) << std::endl;
  std::cout << "sizeof(Colour1)= "  << sizeof(Colour1) << std::endl;
  std::cout << "sizeof(Colour2)= "  << sizeof(Colour2) << std::endl;
  std::cout << "sizeof(Colour3)= "  << sizeof(Colour3) << std::endl;
  
  std::cout << std::endl;

  std::cout << "Colour0::red: " << static_cast<bool>(Colour0::red) << std::endl;
  std::cout << "red: " << red << std::endl;
  std::cout << "Colour2::red: " << static_cast<char>(Colour2::red) << std::endl;
  std::cout << "Colour3::red: " << static_cast<long long int>(Colour3::red) << std::endl;

}

 

My in Microsoft Visual Studio 12.0 included C++ compiler cl.exe can not evaluate the expression std::numeric_limits<long long int>::min() (line 24) at compile time. According to the C++11 standard is std::numeric_limits<long long int>::min() a constant expression. Therefore, I can use this expression to initialize an enumerator. Because of the missing feature in cl.exe I have to use the macro LLONG_MIN in line 25. This macro is defined in the same header as the expression std::numeric_limits: <climits>.

 At the end the output.

 enumType

What's next?

Typically, you have in the embedded world a system of systems. Or to say it different. Many autonomous systems interact with each other to build the whole system. If I change the term autonomous system with object we are in the domain of object-oriented programming. From my perspective the object-oriented abstraction is an abstraction with a great added value for the deeper understanding of embedded systems. Therefore, I will write in the next post about the new keywords override and final which empowers you to manage the object hierarchies.

 

 

 

 

 

 

 

 

 

 

 

title page smalltitle page small Go to Leanpub/cpplibrary "What every professional C++ programmer should know about the C++ standard library".   Get your e-book. Support my blog.

 

 

 

Tags: enum

Comments   

0 #1 Leanne 2016-11-16 23:07
I want to get across my love for your generosity
in support of folks who actually nee help on this particular subject matter.

Your special dedication to passing the solution throughout turned out to be extraordinarily advantageous and
hafe frequently madee guys like me to get tto their endeavors.
This interesting advice indicates a lot to me and further more
to my colleagues. Best wishes; from all of us.
Quote
0 #2 www.rehabs.com 2016-11-24 05:45
Excellent post. I definitely love this website. Thanks!
Quote
0 #3 Twyla 2016-11-28 05:54
After going ovr a handful of tthe blog articles on yoour
website, I seeriously apprehiate your technique of writing a blog.
I saved it to my bookmark site list and will be
checking back soon. Please visit my web site too and llet me know what
you think.
Quote
0 #4 Linnie 2016-12-09 07:09
Greetings! This is my first visit to your blog! We are a team of volunteers and starting a new initiative in a community in the same niche.
Your blog provided us useful information to work on. You
have done a wonderful job!
Quote
0 #5 Rafael 2016-12-22 03:37
Hello.This article was reaply remarkable, particularly since I was searching for thougyhts
onn this topic llast Saturday.
Quote
0 #6 Christopher 2017-01-05 18:46
Excellent, what a web site it is! This webpage gives useful facts to us,
keep it up.
Quote
0 #7 Nora 2017-03-05 01:51
Pretty nice post. I simply stumbled upon your weblog and wished to say that I have really enjoyed browsing your weblog posts.
In any case I'll be subscribing to your rss feed and I'm hoping you write again soon!
Quote
0 #8 Jasmine 2017-04-24 23:26
I am really delighted to read this website posts which carries plenty of valuable information,
thanks for providing such data.
Quote

Add comment


My Newest E-Book

Latest comments

Subscribe to the newsletter (+ pdf bundle)

Blog archive

Source Code

Visitors

Today 138

All 279146

Currently are 190 guests and no members online