title: Searchable Enum-like object with string and int conversion
body: <h2>Intro</h2>
  
  <p>The <code>enum</code> type in C++ is fairly basic; it basically just creates a bunch of compile-time values for labels (potentially with proper scoping with <code>enum class</code>).</p>
  
  <p>It's very attractive for grouping related compile-time constants together:</p>
  
  <pre><code>enum class Animal{
  DOG, 
  CAT,
  COW,
  ...
  };
  // ...
  Animal myAnimal = Animal::DOG;
  </code></pre>
  
  <p>However it has a variety of perceived shortcomings, including:</p>
  
  <ul>
  <li>No standard way to get the number of possible elements</li>
  <li>No iteration over elements</li>
  <li>No easy association of enum with string</li>
  </ul>
  
  <p>In this post, I seek to create a type that addresses those perceived shortcomings.</p>
  
  <p>An ideal solution takes the notion of compile-time knowledge of constants and their associations with strings and groups them together into an scoped-enum-like object that is searchable both by enum id and enum string name. Finally, the resulting type would use syntax that is as close to enum syntax as possible.</p>
  
  <p>In this post I'll first outline what others have attempted for the individual pieces, and then walk through two approaches, one that accomplishes the above but has undefined behavior due to order of initialization of static members, and another solution that has less-pretty syntax but no undefined behavior due to order of initialization.</p>
  
  <hr>
  
  <h2>Prior work</h2>
  
  <p>There are plenty of questions on SO about getting the number of items in an enum (<a href="https://stackoverflow.com/q/2102582/27678">1</a> <a href="https://stackoverflow.com/questions/12972317/count-on-enum-c-automatic">2</a> <a href="https://stackoverflow.com/questions/712463/number-of-elements-in-an-enum">3</a>) and plenty of other questions on the web asking the same thing (<a href="http://bytes.com/topic/c/answers/715586-find-number-elements-enumerated-type" rel="nofollow noreferrer">4</a> <a href="http://bytes.com/topic/c/answers/587699-number-elements-enum" rel="nofollow noreferrer">5</a> <a href="http://www.codeproject.com/Questions/207914/To-get-Number-of-elements-in-typedef-struct" rel="nofollow noreferrer">6</a>) etc. And the general consensus is that there's no sure-fire way to do it. </p>
  
  <h3>The N'th element trick</h3>
  
  <p>The following pattern only works if you enforce that enum values are positive and increasing:</p>
  
  <pre><code>enum Foo{A=0, B, C, D, FOOCOUNT}; // FOOCOUNT is 4
  </code></pre>
  
  <p>But is easily broken if you're trying to encode some sort of business logic that requires arbitrary values:</p>
  
  <pre><code>enum Foo{A=-1, B=120, C=42, D=6, FOOCOUNT}; // ????
  </code></pre>
  
  <h3>Boost Enum</h3>
  
  <p>And so the developers at Boost attempted to solve the issue with <a href="https://stackoverflow.com/a/439004/27678">Boost.Enum</a> which uses some fairly complicated macros to expand into some code that will at least give you the size.</p>
  
  <h3>Iterable Enums</h3>
  
  <p>There have been a few attempts at iterable enums; enum-like objects that one can iterate over, theoretically allowing for implicit size computation, or even explicitly in the case of [7] (<a href="https://codereview.stackexchange.com/questions/57626/iterable-enum-class-in-c11">7</a> <a href="https://stackoverflow.com/questions/1390703/enumerate-over-an-enum-in-c">8</a> <a href="https://stackoverflow.com/questions/8498300/allow-for-range-based-for-with-enum-classes">9</a>, ...)</p>
  
  <h3>Enum to String conversion</h3>
  
  <p>Attempts to implement this usually result in free-floating functions and the use of macros to call them appropriately. (<a href="https://stackoverflow.com/questions/28828957/enum-to-string-in-modern-c-and-future-c17">8</a> <a href="https://stackoverflow.com/questions/6281461/enum-to-string-c">9</a> <a href="https://stackoverflow.com/questions/201593/is-there-a-simple-script-to-convert-c-enum-to-string">10</a>)</p>
  
  <p>This also covers searching enums by string (<a href="https://stackoverflow.com/questions/207976/how-to-easily-map-c-enums-to-strings">13</a>)</p>
  
  <hr>
  
  <h2>Additional Constraints</h2>
  
  <ul>
  <li><h3>No macros</h3>
  
  <p>Yes, this means no Boost.Enum or similar approach</p></li>
  <li><h3>Need int->Enum and Enum-int Conversion</h3>
  
  <p>A rather unique problem when you start moving away from <em>actual</em> enums; </p></li>
  <li><h3>Need to be able to find enum by int (or string)</h3>
  
  <p>Also a problem one runs into when they move away from actual enums. The list of enums is considered a collection, and the user wants to interrogate it for specific, <em>known-at-compile-time</em> values. (See <em>iterable enums</em> and <em>Enum to String conversion</em>)</p></li>
  </ul>
  
  <p>At this point it becomes pretty clear that we cannot really use an enum anymore. However, I'd still like an enum-like interface for the user</p>
  
  <h2>Approach</h2>
  
  <p>Let's say I think that I'm super clever and realize that if I have some class <code>A</code>:</p>
  
  <pre><code>struct A
  {
     static int myInt;
  };
  int A::myInt;
  </code></pre>
  
  <p>Then I can access <code>myInt</code> by saying <code>A::myInt</code>.</p>
  
  <p>Which is the same way I'd access an <code>enum</code>:</p>
  
  <pre><code>enum A{myInt};
  // ...
  // A::myInt
  </code></pre>
  
  <p>I say to myself: well I know all my enum values ahead of time, so an enum is basically like this:</p>
  
  <pre><code>struct MyEnum
  {
      static const int A;
      static const int B;
      // ...
  };
  
  const int MyEnum::A = 0;
  const int MyEnum::B = 1;
  // ...
  </code></pre>
  
  <hr>
  
  <p>Next, I want to get fancier; let's address the constraint where we need <code>std::string</code> and <code>int</code> conversions:</p>
  
  <pre><code>struct EnumValue
  {
      EnumValue(std::string _name): name(std::move(_name)), id(gid){++gid;}
      std::string name;
      int id;
      operator std::string() const
      {
         return name;
      }
  
      operator int() const
      {
         return id;
      }
  
      private:
          static int gid;
  };
  
  int EnumValue::gid = 0;
  </code></pre>
  
  <p>And then I can declare some containing class with <code>static</code> <code>EnumValue</code>s:</p>
  
  <h3>MyEnum v1</h3>
  
  <pre><code>class MyEnum
  {
      public:
      static const EnumValue Alpha;
      static const EnumValue Beta;
      static const EnumValue Gamma;
  
  };
  
  const EnumValue MyEnum::Alpha = EnumValue("Alpha")
  const EnumValue MyEnum::Beta  = EnumValue("Beta")
  const EnumValue MyEnum::Gamma  = EnumValue("Gamma")
  </code></pre>
  
  <p>Great! That solves some of our constraints, but how about searching the collection? Hm, well if we now add a <code>static</code> container like <code>unordered_map</code>, then things get even cooler! Throw in some <code>#define</code>s to alleviate string typos, too:</p>
  
  <hr>
  
  <h3>MyEnum v2</h3>
  
  <pre><code>#define ALPHA "Alpha"
  #define BETA "Beta"
  #define GAMMA "Gamma"
  // ...
  
  class MyEnum
  {
      public:
      static const EnumValue&amp; Alpha;
      static const EnumValue&amp; Beta;
      static const EnumValue&amp; Gamma;
      static const EnumValue&amp; StringToEnumeration(std::string _in)
      {
          return enumerations.find(_in)-&gt;second;
      }
  
      static const EnumValue&amp; IDToEnumeration(int _id)
      {
          auto iter = std::find_if(enumerations.cbegin(), enumerations.cend(), 
          [_id](const map_value_type&amp; vt)
          { 
              return vt.second.id == _id;
          });
          return iter-&gt;second;
      }
  
      static const size_t size()
      {
          return enumerations.size();
      }
  
      private:
      typedef std::unordered_map&lt;std::string, EnumValue&gt;  map_type ;
      typedef map_type::value_type map_value_type ;
      static const map_type enumerations;
  };
  
  
  const std::unordered_map&lt;std::string, EnumValue&gt; MyEnum::enumerations =
  { 
      {ALPHA, EnumValue(ALPHA)}, 
      {BETA, EnumValue(BETA)},
      {GAMMA, EnumValue(GAMMA)}
  };
  
  const EnumValue&amp; MyEnum::Alpha = enumerations.find(ALPHA)-&gt;second;
  const EnumValue&amp; MyEnum::Beta  = enumerations.find(BETA)-&gt;second;
  const EnumValue&amp; MyEnum::Gamma  = enumerations.find(GAMMA)-&gt;second;
  </code></pre>
  
  <h2><a href="http://coliru.stacked-crooked.com/a/7132812433032430" rel="nofollow noreferrer">Full working demo HERE!</a></h2>
  
  <hr>
  
  <p>Now I get the added benefit of searching the container of enums by <code>name</code> or <code>id</code>: </p>
  
  <pre><code>std::cout &lt;&lt; MyEnum::StringToEnumeration(ALPHA).id &lt;&lt; std::endl; //should give 0
  std::cout &lt;&lt; MyEnum::IDToEnumeration(0).name &lt;&lt; std::endl; //should give "Alpha"
  </code></pre>
  
  <h1>BUT</h1>
  
  <p>This all feels very wrong. We're initializing a LOT of static data. I mean, it wasn't until recently that we could populate a <code>map</code> at compile time! (<a href="https://stackoverflow.com/a/2172056/27678">11</a>)</p>
  
  <p>Then there's the issue of the <a href="https://isocpp.org/wiki/faq/ctors#static-init-order" rel="nofollow noreferrer">static-initialization order fiasco</a>:</p>
  
  <blockquote>
    <p>A subtle way to crash your program.</p>
    
    <p>The static initialization order fiasco is a very subtle and commonly
    misunderstood aspect of C++. Unfortunately it’s very hard to detect —
    the errors often occur before main() begins.</p>
    
    <p>In short, suppose you have two static objects x and y which exist in
    separate source files, say x.cpp and y.cpp. Suppose further that the
    initialization for the y object (typically the y object’s constructor)
    calls some method on the x object.</p>
    
    <p>That’s it. It’s that simple.</p>
    
    <p>The tragedy is that you have a 50%-50% chance of dying. If the
    compilation unit for x.cpp happens to get initialized first, all is
    well. But if the compilation unit for y.cpp get initialized first,
    then y’s initialization will get run before x’s initialization, and
    you’re toast. E.g., y’s constructor could call a method on the x
    object, yet the x object hasn’t yet been constructed.</p>
    
    <p>I hear they’re hiring down at McDonalds. Enjoy your new job flipping
    burgers.</p>
    
    <p>If you think it’s “exciting” to play Russian Roulette with live rounds
    in half the chambers, you can stop reading here. On the other hand if
    you like to improve your chances of survival by preventing disasters
    in a systematic way, you probably want to read the next FAQ.</p>
    
    <p>Note: The static initialization order fiasco can also, in some cases,
    apply to built-in/intrinsic types.</p>
  </blockquote>
  
  <p>Which can be mediated with a getter function that initializes your static data and returns it (<a href="https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use" rel="nofollow noreferrer">12</a>):</p>
  
  <pre><code>Fred&amp; GetFred()
  {
    static Fred* ans = new Fred();
    return *ans;
  }
  </code></pre>
  
  <p>But if I do that, now I have to call a function to initialize my static data, and I lose the pretty syntax you see above!</p>
  
  <p><s>#Questions#
  So, now I finally get around to my questions:</p>
  
  <ul>
  <li>Be honest, how bad is the above approach? In terms of initialization order safety and maintainability?</li>
  <li>What kind of alternatives do I have that are still pretty <em>for the end user</em>?
  </s></li>
  </ul>
  
  <hr>
  
  <h1>EDIT</h1>
  
  <p>The comments on this post seem to indicate a strong preference for static accessor functions to get around the static order initialization problem:</p>
  
  <pre><code> public:
      typedef std::unordered_map&lt;std::string, EnumValue&gt; map_type ;
      typedef map_type::value_type map_value_type ;
  
      static const map_type&amp; Enumerations()
      {
          static map_type enumerations {
              {ALPHA, EnumValue(ALPHA)}, 
              {BETA, EnumValue(BETA)},
              {GAMMA, EnumValue(GAMMA)}
              };
  
          return enumerations;
      }
  
      static const EnumValue&amp; Alpha()
      {
          return Enumerations().find(ALPHA)-&gt;second;
      }
  
      static const EnumValue&amp; Beta()
      {
           return Enumerations().find(BETA)-&gt;second;
      }
  
      static const EnumValue&amp; Gamma()
      {
          return Enumerations().find(GAMMA)-&gt;second;
      }
  </code></pre>
  
  <h2><a href="http://coliru.stacked-crooked.com/a/2d7ea5a012e392c1" rel="nofollow noreferrer">Full working demo v2 HERE</a></h2>
  
  <h2>Questions</h2>
  
  <p>My Updated questions are as follows:</p>
  
  <ul>
  <li>Is there another way around the static order initialization problem?</li>
  <li><p>Is there a way to perhaps only use the accessor function to initialize the <code>unordered_map</code>, but still (safely) be able to access the "enum" values with enum-like syntax? e.g.:</p>
  
  <p><code>MyEnum::Enumerations()::Alpha</code></p></li>
  </ul>
  
  <p>or</p>
  
  <pre><code>MyEnum::Alpha
  </code></pre>
  
  <p>Instead of what I currently have:</p>
  
  <pre><code>MyEnum::Alpha()
  </code></pre>
  
  <h3>Regarding the bounty:</h3>
  
  <p>I believe an answer to this question will also solve the issues surrounding enums I've elaborated in the post (Enum is in quotes because the resulting type will not be an enum, but we want enum-like behavior):</p>
  
  <ul>
  <li>getting the size of an "enum"</li>
  <li>string to "enum" conversion </li>
  <li>a searchable "enum". </li>
  </ul>
  
  <p>Specifically, if we could do what I've already done, but somehow accomplish syntax that is enum-like while enforcing static initialization order, I think that would be acceptable </p>