{"id":5399,"date":"2018-03-03T07:04:51","date_gmt":"2018-03-03T07:04:51","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-to-switch-or-not-to-switch-that-is-the-question\/"},"modified":"2023-06-26T11:55:35","modified_gmt":"2023-06-26T11:55:35","slug":"c-core-guidelines-to-switch-or-not-to-switch-that-is-the-question","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-to-switch-or-not-to-switch-that-is-the-question\/","title":{"rendered":"C++ Core Guidelines: To Switch or not to Switch, that is the Question"},"content":{"rendered":"<p>First, I have to apologize. Today, I wanted to continue my journey through the C++ Core Guidelines with arithmetic expressions. In my seminar this week, we had a long discussion about <span style=\"font-family: 'courier new', courier;\">switch<\/span>&nbsp;statements in C\/C++ and how they become unmaintainable. Honestly, I&#8217;m not a fan of the&nbsp;<span style=\"font-family: 'courier new', courier;\">switch<\/span> statements, and I have to say: there is life after the <span style=\"font-family: 'courier new', courier;\">switch<\/span> statements.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5396\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/hamlet.png\" alt=\"hamlet\" width=\"400\" height=\"583\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/hamlet.png 878w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/hamlet-206x300.png 206w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/hamlet-702x1024.png 702w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/hamlet-768x1120.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/>&nbsp;<\/p>\n<p>Before I write about the discussion and, in particular, one way to overcome the <span style=\"font-family: courier new, courier;\">switch<\/span> statement, here is at first my plan for today.<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-break\" style=\"color: #268bd2; text-decoration: none;\">ES.78: Always end a non-empty&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">case<\/code>&nbsp;with a&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">break<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-default\" style=\"color: #268bd2; text-decoration: none;\">ES.79: Use&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">default<\/code>&nbsp;to handle common cases (only)<\/a><\/li>\n<\/ul>\n<p>Let&#8217;s dive directly into the <span style=\"font-family: 'courier new', courier;\">switch<\/span> statements.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-break\" style=\"color: #268bd2; text-decoration: none;\">ES.78: Always end a non-empty&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">case<\/code>&nbsp;with a&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">break<\/code><\/a><\/h3>\n<p>I saw <span style=\"font-family: 'courier new', courier;\">switch<\/span> statements which more than a hundred case labels. If you use non-empty cases without a break, the maintenance of this <span style=\"font-family: 'courier new', courier;\">switch<\/span> statements becomes a maintenance nightmare. Here is a first example of the guidelines:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">switch<\/span> (eventType) {\r\n<span style=\"color: #006699; font-weight: bold;\">case<\/span> Information:\r\n    update_status_bar();\r\n    <span style=\"color: #006699; font-weight: bold;\">break<\/span>;\r\n<span style=\"color: #006699; font-weight: bold;\">case<\/span> Warning:\r\n    write_event_log();\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ Bad - implicit fallthrough<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">case<\/span> Error:\r\n    display_error_window();\r\n    <span style=\"color: #006699; font-weight: bold;\">break<\/span>;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Maybe, you overlooked it. The <span style=\"font-family: 'courier new', courier;\">Warning<\/span> case has no break statement; therefore, the <span style=\"font-family: 'courier new', courier;\">Error<\/span> case will automatically be executed.&nbsp;<\/p>\n<p>Since C++17, we have a cure with the attribute <span style=\"font-family: 'courier new', courier;\">[[fallthrough]]<\/span>. Now, you can explicitly express your intent. <span style=\"font-family: 'courier new', courier;\">[[fallthrough]]<\/span> has to be on its own line immediately before a&nbsp;<span style=\"font-family: 'courier new', courier;\">case<\/span>&nbsp;label and indicates that a fallthrough is intentional and should, therefore, not diagnose a compiler warning.<\/p>\n<p style=\"margin: 0px 0px 10px; color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\">Here is a small example.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">f<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> n) {\r\n  <span style=\"color: #007788; font-weight: bold;\">void<\/span> g(), h(), i();\r\n  <span style=\"color: #006699; font-weight: bold;\">switch<\/span> (n) {\r\n    <span style=\"color: #006699; font-weight: bold;\">case<\/span> <span style=\"color: #ff6600;\">1<\/span>:\r\n    <span style=\"color: #006699; font-weight: bold;\">case<\/span> <span style=\"color: #ff6600;\">2<\/span>:\r\n      g();\r\n      [[fallthrough]];\r\n    <span style=\"color: #006699; font-weight: bold;\">case<\/span> <span style=\"color: #ff6600;\">3<\/span>: <span style=\"color: #0099ff; font-style: italic;\">\/\/ no warning on fallthrough (1)<\/span>\r\n      h(); \r\n    <span style=\"color: #006699; font-weight: bold;\">case<\/span> <span style=\"color: #ff6600;\">4<\/span>: <span style=\"color: #0099ff; font-style: italic;\">\/\/ compiler may warn on fallthrough (2)<\/span>\r\n      i();\r\n      [[fallthrough]]; <span style=\"color: #0099ff; font-style: italic;\">\/\/ ill&shy;formed, not before a case label (3)<\/span>\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">The<\/span><span style=\"color: #444444; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; font-family: 'courier new', courier;\">&nbsp;[[fallthrough]]<\/span><span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;attribute in line (1) suppresses a compiler warning. That will not hold for line (2). The compiler may warn. Line (3) is ill-formed because no&nbsp;<\/span><span style=\"color: #444444; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; font-family: 'courier new', courier;\">case<\/span><span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;label is following.<\/span><\/p>\n<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-default\" style=\"color: #268bd2; text-decoration: none;\">ES.79: Use&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">default<\/code>&nbsp;to handle common cases (only)<\/a><\/h3>\n<p>Here is my contrived example to make the rule clear.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ switch.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">enum<\/span> <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Message<\/span>{\r\n  information,\r\n  warning,\r\n  error,\r\n  fatal\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">writeMessage<\/span>(){ std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"message\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; }\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">writeWarning<\/span>(){ std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"warning\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; }\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">writeUnexpected<\/span>(){ std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"unexpected\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; }\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">withDefault<\/span>(Message mess){\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">switch<\/span>(mess){\r\n    <span style=\"color: #006699; font-weight: bold;\">case<\/span> Message:<span style=\"color: #555555;\">:<\/span>information<span style=\"color: #555555;\">:<\/span>\r\n      writeMessage();\r\n      <span style=\"color: #006699; font-weight: bold;\">break<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">case<\/span> Message:<span style=\"color: #555555;\">:<\/span>warning<span style=\"color: #555555;\">:<\/span>\r\n      writeWarning();\r\n      <span style=\"color: #006699; font-weight: bold;\">break<\/span>;\r\n    <span style=\"color: #9999ff;\">default:<\/span>\r\n      writeUnexpected();\r\n      <span style=\"color: #006699; font-weight: bold;\">break<\/span>;\r\n  }\r\n  \r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">withoutDefaultGood<\/span>(Message mess){\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">switch<\/span>(mess){\r\n    <span style=\"color: #006699; font-weight: bold;\">case<\/span> Message:<span style=\"color: #555555;\">:<\/span>information<span style=\"color: #555555;\">:<\/span>\r\n      writeMessage();\r\n      <span style=\"color: #006699; font-weight: bold;\">break<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">case<\/span> Message:<span style=\"color: #555555;\">:<\/span>warning<span style=\"color: #555555;\">:<\/span>\r\n      writeWarning();\r\n      <span style=\"color: #006699; font-weight: bold;\">break<\/span>;\r\n    <span style=\"color: #9999ff;\">default:<\/span>\r\n      <span style=\"color: #0099ff; font-style: italic;\">\/\/ nothing can be done             \/\/ (1)<\/span>\r\n      <span style=\"color: #006699; font-weight: bold;\">break<\/span>;\r\n  }\r\n  \r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">withoutDefaultBad<\/span>(Message mess){\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">switch<\/span>(mess){\r\n    <span style=\"color: #006699; font-weight: bold;\">case<\/span> Message:<span style=\"color: #555555;\">:<\/span>information<span style=\"color: #555555;\">:<\/span>\r\n      writeMessage();\r\n      <span style=\"color: #006699; font-weight: bold;\">break<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">case<\/span> Message:<span style=\"color: #555555;\">:<\/span>warning<span style=\"color: #555555;\">:<\/span>\r\n      writeWarning();\r\n      <span style=\"color: #006699; font-weight: bold;\">break<\/span>;\r\n  }\r\n  \r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  withDefault(Message<span style=\"color: #555555;\">::<\/span>fatal);\r\n  withoutDefaultGood(Message<span style=\"color: #555555;\">::<\/span>information);\r\n  withoutDefaultBad(Message<span style=\"color: #555555;\">::<\/span>warning);\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The implementation of the functions <span style=\"font-family: 'courier new', courier;\">withDefault<\/span> and <span style=\"font-family: 'courier new', courier;\">withoutDefaultGood<\/span> are expressive enough. A maintainer of the function knows because of comment (1) that there is no default case for this switch statement. Compare the function <span style=\"font-family: 'courier new', courier;\">withoutDefaultGood<\/span> and <span style=\"font-family: 'courier new', courier;\">withoutDefaultBad<\/span> from a maintenance point of view. Do you know if the function implementer <span style=\"font-family: 'courier new', courier;\">withoutDefaultBad<\/span> forgot the default case or if the enumerator&#8217;s <span style=\"font-family: 'courier new', courier;\">Message::error<\/span> and <span style=\"font-family: 'courier new', courier;\">Message::fatal<\/span> were later added? At least, you have to study the source code or ask the original authors, if possible.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5397\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/switch.png\" alt=\"switch\" width=\"300\" height=\"176\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/switch.png 396w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/switch-300x177.png 300w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>I mentioned already that I had in my last seminar an intensive discussion about switch&nbsp;statements in C\/C++. I forget to mention. It gave a Python seminar. Python has no switch statement. There is still life after the switch statement in Python and maybe in C++. What is called in Python, a dictionary is typically coined hashtable or unordered associative container in C++. We have had it since C++11. The official name is <span style=\"font-family: 'courier new', courier;\">std::unordered_map<\/span>, and it guarantees constant amortized time. This means independent of the size of <span style=\"font-family: 'courier new', courier;\">std::unordered_map<\/span> you get your answer at the same time.<\/p>\n<p>My key takeaway is that a <span style=\"font-family: 'courier new', courier;\">std::unordered_map<\/span> is not only a data structure. A <span style=\"font-family: 'courier new', courier;\">std::unordered_map<\/span> is also a control structure for simulating a switch statement. This technique is called <a href=\"https:\/\/en.wikipedia.org\/wiki\/Dispatch_table\">dispatch table<\/a>. I already wrote a post about <a href=\"https:\/\/www.modernescpp.com\/index.php\/functional-in-c-dispatch-table\">Functional in C++11 and C++14: Dispatch Table und Generic Lambdas<\/a>.<span style=\"color: #242729; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\"><br \/><\/span><\/p>\n<p>To prove my point, I will implement the program <span style=\"font-family: 'courier new', courier;\">switch.cpp<\/span> one more by using an <span style=\"font-family: 'courier new', courier;\">std::unoredered_map<\/span>. For simplicity reasons, I will use a global hash table.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ switchDict.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;functional&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;unordered_map&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">enum<\/span> <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Message<\/span>{\r\n  information,\r\n  warning,\r\n  error,\r\n  fatal\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">writeMessage<\/span>(){ std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"message\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; }\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">writeWarning<\/span>(){ std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"warning\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; }\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">writeUnexpected<\/span>(){ std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"unexpected\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; }\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>unordered_map<span style=\"color: #555555;\">&lt;<\/span>Message, std<span style=\"color: #555555;\">::<\/span>function<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">void<\/span>()<span style=\"color: #555555;\">&gt;&gt;<\/span> mess2Func{         \/\/ (1)\r\n    {Message<span style=\"color: #555555;\">::<\/span>information, writeMessage},\r\n    {Message<span style=\"color: #555555;\">::<\/span>warning, writeWarning}\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">withDefault<\/span>(Message mess){\r\n    \r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> pair <span style=\"color: #555555;\">=<\/span> mess2Func.find(mess);\r\n  <span style=\"color: #006699; font-weight: bold;\">if<\/span> (pair <span style=\"color: #555555;\">!=<\/span> mess2Func.end()){\r\n      pair<span style=\"color: #555555;\">-&gt;<\/span>second();\r\n  }\r\n  <span style=\"color: #006699; font-weight: bold;\">else<\/span>{\r\n      writeUnexpected();\r\n  }\r\n  \r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">withoutDefaultGood<\/span>(Message mess){\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> pair <span style=\"color: #555555;\">=<\/span> mess2Func.find(mess);\r\n  <span style=\"color: #006699; font-weight: bold;\">if<\/span> (pair <span style=\"color: #555555;\">!=<\/span> mess2Func.end()){\r\n      pair<span style=\"color: #555555;\">-&gt;<\/span>second();\r\n  }\r\n  <span style=\"color: #006699; font-weight: bold;\">else<\/span>{\r\n      <span style=\"color: #0099ff; font-style: italic;\">\/\/ Nothing can be done<\/span>\r\n  }\r\n  \r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">withoutDefaultBad<\/span>(Message mess){\r\n  \r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> pair <span style=\"color: #555555;\">=<\/span> mess2Func.find(mess);\r\n  <span style=\"color: #006699; font-weight: bold;\">if<\/span> (pair <span style=\"color: #555555;\">!=<\/span> mess2Func.end()){\r\n      pair<span style=\"color: #555555;\">-&gt;<\/span>second();\r\n  }\r\n  \r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  withDefault(Message<span style=\"color: #555555;\">::<\/span>fatal);\r\n  withoutDefaultGood(Message<span style=\"color: #555555;\">::<\/span>information);\r\n  withoutDefaultBad(Message<span style=\"color: #555555;\">::<\/span>warning);\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>In line (1) is the <span style=\"font-family: 'courier new', courier;\">std::unordered_map<\/span>. I use it in the three functions <span style=\"font-family: 'courier new', courier;\">withDefault, withoutDefaultGood<\/span>, and <span style=\"font-family: 'courier new', courier;\">withoutDefaultBad<\/span>. The output of the program <span style=\"font-family: 'courier new', courier;\">switchDict<\/span>&nbsp;is precisely the same as the output of the program <span style=\"font-family: 'courier new', courier;\">switch.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5398\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/switchDict.png\" alt=\"switchDict\" width=\"500\" height=\"181\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/switchDict.png 692w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/switchDict-300x108.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>Of course, there are a few differences between the switch statement and the hash table. First, a hash table is a modifiable data structure; you can copy or modify it at runtime. Second, there is no fall-through in the hash table. You have to simulate it by adding the function to the key: <span style=\"font-family: 'courier new', courier;\">mess2Func[Message::error] = writeWarning;. <\/span>The same action will happen for the key <span style=\"font-family: 'courier new', courier;\">Message::warning<\/span> and the key&nbsp;<span style=\"font-family: 'courier new', courier;\">Message::error.<\/span><\/p>\n<p>I will not argue about performance because the dispatch table can be executed at compile time, depending on your use case. For example, you can use <span style=\"font-family: 'courier new', courier;\">constexpr<\/span> functions.&nbsp;<\/p>\n<h2>What&#8217;s next<\/h2>\n<p>Sorry for the detour, but the discussion in my seminar was too heavy. <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-more-about-control-structures\">Next time<\/a>, I will write, finish the last rules to statements and start with the rules to arithmetic expressions.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>First, I have to apologize. Today, I wanted to continue my journey through the C++ Core Guidelines with arithmetic expressions. In my seminar this week, we had a long discussion about switch&nbsp;statements in C\/C++ and how they become unmaintainable. Honestly, I&#8217;m not a fan of the&nbsp;switch statements, and I have to say: there is life [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":5396,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[491,459,490],"class_list":["post-5399","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-control-structures","tag-lambdas","tag-switch"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5399","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=5399"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5399\/revisions"}],"predecessor-version":[{"id":6837,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5399\/revisions\/6837"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5396"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5399"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5399"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5399"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}