title: enum to string in modern C++11 / C++14 / C++17 and future C++20
body: <h3>Contrary to all other similar questions, this question is about using the new C++ features.</h3>
  <ul>
  <li>2008 <a href="/questions/tagged/c" class="post-tag" title="show questions tagged &#39;c&#39;" rel="tag">c</a> <a href="/questions/201593">Is there a simple way to convert C++ enum to string?</a></li>
  <li>2008 <a href="/questions/tagged/c" class="post-tag" title="show questions tagged &#39;c&#39;" rel="tag">c</a> <a href="/questions/147267">Easy way to use variables of enum types as string in C?</a></li>
  <li>2008 <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> <a href="/questions/207976">How to easily map c++ enums to strings</a></li>
  <li>2008 <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> <a href="/questions/126277">Making something both a C identifier and a string?</a></li>
  <li>2008 <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> <a href="/questions/201593">Is there a simple script to convert C++ enum to string?</a></li>
  <li>2009 <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> <a href="/questions/1448396">How to use enums as flags in C++?</a></li>
  <li>2011 <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> <a href="/questions/5093460">How to convert an enum type variable to a string?</a></li>
  <li>2011 <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> <a href="/questions/6281461">Enum to String C++</a></li>
  <li>2011 <a href="/questions/tagged/c%2b%2b" class="post-tag" title="show questions tagged &#39;c++&#39;" rel="tag">c++</a> <a href="/questions/5093460">How to convert an enum type variable to a string?</a></li>
  <li>2012 <a href="/questions/tagged/c" class="post-tag" title="show questions tagged &#39;c&#39;" rel="tag">c</a> <a href="/questions/9907160">How to convert enum names to string in c</a></li>
  <li>2013 <a href="/questions/tagged/c" class="post-tag" title="show questions tagged &#39;c&#39;" rel="tag">c</a> <a href="/questions/18790332">Stringifying an conditionally compiled enum in C</a></li>
  </ul>
  <h3>After reading many answers, I did not yet find any:</h3>
  <ul>
  <li>Elegant way using <a href="https://en.wikipedia.org/wiki/C%2B%2B11" rel="noreferrer">C++11</a>, <a href="https://en.wikipedia.org/wiki/C%2B%2B14" rel="noreferrer">C++14</a> or <a href="https://en.wikipedia.org/wiki/C%2B%2B17" rel="noreferrer">C++17</a> new features</li>
  <li>Or something ready-to-use in <a href="http://www.boost.org/doc/libs/release/" rel="noreferrer">Boost</a></li>
  <li>Else something planned for <a href="https://en.wikipedia.org/wiki/C%2B%2B20" rel="noreferrer">C++20</a></li>
  </ul>
  <h3>Example</h3>
  <p>An example is often better than a long explanation.<br />
  You can compile and run this snippet on <a href="http://coliru.stacked-crooked.com/a/5fd889116289d906" rel="noreferrer">Coliru</a>.<br />
  <sup>(<a href="http://coliru.stacked-crooked.com/a/bb58819257b6df50" rel="noreferrer">Another former example</a> is also available)</sup></p>
  <pre><code>#include &lt;map&gt;
  #include &lt;iostream&gt;
  
  struct MyClass
  {
      enum class MyEnum : char {
          AAA = -8,
          BBB = '8',
          CCC = AAA + BBB
      };
  };
  
  // Replace magic() by some faster compile-time generated code
  // (you're allowed to replace the return type with std::string
  // if that's easier for you)
  const char* magic (MyClass::MyEnum e)
  {
      const std::map&lt;MyClass::MyEnum,const char*&gt; MyEnumStrings {
          { MyClass::MyEnum::AAA, &quot;MyClass::MyEnum::AAA&quot; },
          { MyClass::MyEnum::BBB, &quot;MyClass::MyEnum::BBB&quot; },
          { MyClass::MyEnum::CCC, &quot;MyClass::MyEnum::CCC&quot; }
      };
      auto   it  = MyEnumStrings.find(e);
      return it == MyEnumStrings.end() ? &quot;Out of range&quot; : it-&gt;second;
  }
  
  int main()
  {
     std::cout &lt;&lt; magic(MyClass::MyEnum::AAA) &lt;&lt;'\n';
     std::cout &lt;&lt; magic(MyClass::MyEnum::BBB) &lt;&lt;'\n';
     std::cout &lt;&lt; magic(MyClass::MyEnum::CCC) &lt;&lt;'\n';
  }
  </code></pre>
  <h3>Constraints</h3>
  <ul>
  <li>Please no valueless duplication of <a href="/a/10177840/938111">other answers</a> or <a href="/a/18791363/938111">basic link</a>.</li>
  <li>Please avoid bloat macro-based answer, or try to reduce the <code>#define</code> overhead as minimum as possible.</li>
  <li>Please no manual <code>enum</code> -&gt; <code>string</code> mapping.</li>
  </ul>
  <h3>Nice to have</h3>
  <ul>
  <li>Support <code>enum</code> values starting from a number different from zero</li>
  <li>Support negative <code>enum</code> values</li>
  <li>Support fragmented <code>enum</code> values</li>
  <li>Support <code>class enum</code> (C++11)</li>
  <li>Support <code>class enum : &lt;type&gt;</code> having any allowed <code>&lt;type&gt;</code> (C++11)</li>
  <li>Compile-time (not run-time) conversions to a string,<br>
  or at least fast execution at run-time (e.g. <code>std::map</code> is not a great idea...)</li>
  <li><a href="https://en.cppreference.com/w/cpp/language/constexpr" rel="noreferrer"><code>constexpr</code></a> (C++11, then relaxed in C++14/17/20)</li>
  <li><a href="https://en.cppreference.com/w/cpp/language/noexcept" rel="noreferrer"><code>noexcept</code></a> (C++11)</li>
  <li><a href="https://en.wikipedia.org/wiki/C%2B%2B17" rel="noreferrer">C++17</a>/<a href="https://en.wikipedia.org/wiki/C%2B%2B20" rel="noreferrer">C++20</a> friendly snippet</li>
  </ul>
  <p>One possible idea could be using the C++ compiler capabilities to generate C++ code at compilation-time using meta-programming tricks based on <code>variadic template class</code> and <code>constexpr</code> functions...</p>