{"id":5009,"date":"2016-11-01T16:40:14","date_gmt":"2016-11-01T16:40:14","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/strongly-typed-enums\/"},"modified":"2023-06-26T12:37:42","modified_gmt":"2023-06-26T12:37:42","slug":"strongly-typed-enums","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/strongly-typed-enums\/","title":{"rendered":"Strongly-Typed Enums"},"content":{"rendered":"<p>Enumerations are a convenient way to define integer constants with names. These integer constants are called enumerators. Sadly, classical enums have a few drawbacks.<\/p>\n<p><!--more--><\/p>\n<h2>The drawbacks of enumerations in classical C++<\/h2>\n<p>&nbsp;A short reminder. Three drawbacks of enumerations.<span style=\"font-family: courier new,courier;\"><\/span><\/p>\n<ol>\n<li>The enumerators implicitly convert to <span style=\"font-family: courier new,courier;\">int.<\/span><\/li>\n<li>They introduce the enumerators in the enclosing scope.<\/li>\n<li>The type of enumeration can not be specified.<\/li>\n<\/ol>\n<p>First to point 3: Enumerations can not be forward declared because their type is not known. There is only a guarantee for the enumerators in classical C++. The type must be integral and big enough to hold the enumerators.<\/p>\n<p>Point 1 and point 2 are more surprising.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ enumClassic.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\t\r\n  std::cout &lt;&lt; std::endl;\r\n\t\r\n  <span style=\"color: #0000ff;\">enum<\/span> Colour{red= 0,green= 2,blue};\r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"red: \"<\/span> &lt;&lt; red &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"green: \"<\/span> &lt;&lt; green &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"blue: \"<\/span> &lt;&lt; blue &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #2b91af;\">int<\/span> red2= red;\r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"red2: \"<\/span> &lt;&lt; red2 &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #008000;\">\/\/ int red= 5;  ERROR<\/span>\r\n  \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>On the one hand are the enumerators <span style=\"font-family: courier new,courier;\">red,<\/span> <span style=\"font-family: courier new,courier;\">green,<\/span> and <span style=\"font-family: courier new,courier;\">blue<\/span>, known in the enclosing scope. Therefore, the definition of the red variable in line 19 is impossible. On the other hand, <span style=\"font-family: courier new, courier;\">red<\/span> can be implicitly converted to <span style=\"font-family: courier new,courier;\">int.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5005\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumClassic.PNG\" alt=\"enumClassic\" width=\"600\" height=\"185\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumClassic.PNG 758w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumClassic-300x93.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>If you use no name for an enumeration like <span style=\"font-family: courier new,courier;\">enum{red, green, blue},<\/span>&nbsp; the enumerators will be introduced in the enclosing scope.<\/p>\n<p>But that surprise ends with C++11.<\/p>\n<\/p>\n<h2>Strongly-typed enumerations<\/h2>\n<p>The strongly-typed enumerations have to follow stronger rules:<\/p>\n<ol>\n<li>The enumerators can only be accessed in the scope of the enumeration.<\/li>\n<li>The enumerators don&#8217;t implicitly convert to <span style=\"font-family: courier new,courier;\">int.<\/span><span style=\"font-family: Courier New,Courier,monospace;\"><br \/><\/span><\/li>\n<li>The enumerators aren&#8217;t imported in the enclosing scope.<\/li>\n<li>The type of enumerators is, by default, <span style=\"font-family: courier new,courier;\">int.<\/span> Therefore, you can forward the enumeration.<span style=\"font-family: Courier New,Courier,monospace;\"><\/span><\/li>\n<\/ol>\n<p>The syntactical difference between the classic enumerations and the strongly-typed enumerations is minimal. The strongly-typed enumerations additionally get the keyword <span style=\"font-family: courier new,courier;\">class<\/span> or <span style=\"font-family: courier new,courier;\">struct.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5006\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumClassicStrongEng.png\" alt=\"enumClassicStrongEng\" width=\"600\" height=\"132\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumClassicStrongEng.png 812w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumClassicStrongEng-300x66.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumClassicStrongEng-768x168.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>If you want to use an enumerator as an <span style=\"font-family: courier new,courier;\">int,<\/span> you must explicitly convert it with <code>static_cast<\/code><span style=\"font-family: courier new,courier;\">.<\/span><\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ enumCast.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">enum<\/span> OldEnum{\r\n  one= 1,\r\n  ten=10,\r\n  hundred=100,\r\n  thousand= 1000\r\n};\r\n\r\n<span style=\"color: #0000ff;\">enum<\/span> <span style=\"color: #0000ff;\">struct<\/span> NewEnum{\r\n  one= 1,\r\n  ten=10,\r\n  hundred=100,\r\n  thousand= 1000\r\n};\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\t\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"C++11= \"<\/span> &lt;&lt; 2*thousand + 0*hundred + 1*ten + 1*one &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"C++11= \"<\/span> &lt;&lt; 2*<span style=\"color: #0000ff;\">static_cast<\/span>&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;(NewEnum::thousand) + \r\n                            0*<span style=\"color: #0000ff;\">static_cast<\/span>&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;(NewEnum::hundred) + \r\n                            1*<span style=\"color: #0000ff;\">static_cast<\/span>&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;(NewEnum::ten) + \r\n\t                    1*<span style=\"color: #0000ff;\">static_cast<\/span>&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;(NewEnum::one) &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p><!-- HTML generated using hilite.me --><\/p>\n<p>&nbsp;<\/p>\n<p>To calculate or output the enumerators, you must convert them into integral types. Either the addition or the output of strongly-typed enumerations is defined.&nbsp;<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border-width: .1em .1em .1em .8em; padding: .2em .6em;\"><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5007\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumCast.PNG\" alt=\"enumCast\" width=\"600\" height=\"172\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumCast.PNG 678w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumCast-300x86.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/>&nbsp;<\/div>\n<p>&nbsp;<\/p>\n<p>I often speak in this post about classical versus strongly-typed enumerations. Often there are called&nbsp;<strong>scoped and unscoped enumerations<\/strong>.<\/p>\n<h2>Explicitly specifying the type<\/h2>\n<p>I ignored one feature of the enumerations in C++11. You can explicitly specify the type of enumerators. By default, it&#8217;s <span style=\"font-family: courier new,courier;\">int.<\/span><\/p>\n<p>But that does not have to be. You can use integral types like <span style=\"font-family: courier new,courier;\">bool, char, short int, long int, or, long long int<\/span>.&nbsp; Read&nbsp;<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/cc953fe1.aspx?f=255&amp;MSPPError=-2147217396\">msdn.microsoft.com<\/a> for the details. You can read in my post, <a href=\"https:\/\/www.modernescpp.com\/index.php\/check-types\">Check types<\/a> how you can check at compile time if a type is integral.&nbsp;<\/p>\n<p>You can independently use the scoped property and the explicit type specification of an enumeration. Dependent on the base types, the enumerations have different sizes.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ enumType.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;climits&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">enum<\/span> <span style=\"color: #0000ff;\">struct<\/span> Colour0: <span style=\"color: #2b91af;\">bool<\/span>{\r\n  red,     <span style=\"color: #008000;\">\/\/ 0<\/span>\r\n  blue     <span style=\"color: #008000;\">\/\/ 1<\/span>\r\n};\r\n\r\n<span style=\"color: #0000ff;\">enum<\/span> Colour1{\r\n  red= -5,   \r\n  blue,      <span style=\"color: #008000;\">\/\/ -4<\/span>\r\n  green      <span style=\"color: #008000;\">\/\/ -3<\/span>\r\n};\r\n\r\n<span style=\"color: #0000ff;\">enum<\/span> <span style=\"color: #0000ff;\">struct<\/span> Colour2: <span style=\"color: #2b91af;\">char<\/span>{\r\n  red= 100,\r\n  blue, <span style=\"color: #008000;\">\/\/ 101<\/span>\r\n  green <span style=\"color: #008000;\">\/\/ 102<\/span>\r\n};\r\n\r\n<span style=\"color: #0000ff;\">enum<\/span> <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">Colour3<\/span>: <span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">int<\/span>{\r\n  <span style=\"color: #008000;\">\/\/red= \tstd::numeric_limits&lt;long long int&gt;::min();<\/span>\r\n  red= LLONG_MIN,\r\n  blue,    <span style=\"color: #008000;\">\/\/ std::numeric_limits&lt;long long int&gt;::min() + 1<\/span>\r\n  green    <span style=\"color: #008000;\">\/\/ std::numeric_limits&lt;long long int&gt;::min() + 2<\/span>\r\n};\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sizeof(Colour0)= \"<\/span>  &lt;&lt; <span style=\"color: #0000ff;\">sizeof<\/span>(Colour0) &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sizeof(Colour1)= \"<\/span>  &lt;&lt; <span style=\"color: #0000ff;\">sizeof<\/span>(Colour1) &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sizeof(Colour2)= \"<\/span>  &lt;&lt; <span style=\"color: #0000ff;\">sizeof<\/span>(Colour2) &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sizeof(Colour3)= \"<\/span>  &lt;&lt; <span style=\"color: #0000ff;\">sizeof<\/span>(Colour3) &lt;&lt; std::endl;\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Colour0::red: \"<\/span> &lt;&lt; <span style=\"color: #0000ff;\">static_cast<\/span>&lt;<span style=\"color: #2b91af;\">bool<\/span>&gt;(Colour0::red) &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"red: \"<\/span> &lt;&lt; red &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Colour2::red: \"<\/span> &lt;&lt; <span style=\"color: #0000ff;\">static_cast<\/span>&lt;<span style=\"color: #2b91af;\">char<\/span>&gt;(Colour2::red) &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Colour3::red: \"<\/span> &lt;&lt; <span style=\"color: #0000ff;\">static_cast<\/span>&lt;<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">int<\/span>&gt;(Colour3::red) &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>My in Microsoft Visual Studio 12.0 included C++ compiler cl.exe can not evaluate the expression <span style=\"font-family: courier new,courier;\">std::numeric_limits&lt;long long int&gt;::min()<\/span> (line 24) at compile time. According to the C++11 standard, is<span style=\"font-family: courier new,courier;\">&nbsp;std::numeric_limits&lt;long long int&gt;::min()<\/span> 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 <span style=\"font-family: courier new,courier;\"><\/span><span style=\"font-family: courier new,courier;\">LLONG_MIN<\/span> in line 25. This macro is defined in the same header as the expression <span style=\"font-family: courier new,courier;\">std::numeric_limits<\/span>: <span style=\"font-family: courier new,courier;\">&lt;climits&gt;.<\/span><\/p>\n<p>&nbsp;At the end, the output.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5008\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumType.png\" alt=\"enumType\" width=\"778\" height=\"334\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumType.png 778w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumType-300x129.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/enumType-768x330.png 768w\" sizes=\"auto, (max-width: 778px) 100vw, 778px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Typically, you have in the embedded world a system of systems. Or, to say it differently: Many autonomous systems interact with each other to build the whole system. If I change the term autonomous system with the object, we are in the domain of object-oriented programming. From my perspective, object-oriented abstraction is an abstraction with significant added value for a deeper understanding of embedded systems. Therefore, I will write in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/override-and-final\">next post <\/a>about the new keywords <span style=\"font-family: courier new,courier;\">override<\/span> and <span style=\"font-family: courier new,courier;\">final<\/span>, which empowers you to manage the object hierarchies.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Enumerations are a convenient way to define integer constants with names. These integer constants are called enumerators. Sadly, classical enums have a few drawbacks.<\/p>\n","protected":false},"author":21,"featured_media":5005,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[364],"tags":[458],"class_list":["post-5009","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded","tag-enum"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5009","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5009"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5009\/revisions"}],"predecessor-version":[{"id":6931,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5009\/revisions\/6931"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5005"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5009"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5009"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}