title: Is it possible to concatenate two strings of type `const char *` at compile time?
body: <p>Obviously we can concatenate two string literals in a <code>constexpr</code> function, but what about concatenation of a string literal with a string returned by another <code>constexpr</code> function as in the code below?</p>
  
  <pre><code>template &lt;class T&gt;
  constexpr const char * get_arithmetic_size()
  {
      switch (sizeof(T))
      {
      case 1: return "1";
      case 2: return "2";
      case 4: return "4";
      case 8: return "8";
      case 16: return "16";
      default: static_assert(dependent_false_v&lt;T&gt;);
      }
  }
  
  template &lt;class T&gt;
  constexpr std::enable_if_t&lt;std::is_arithmetic_v&lt;T&gt;, const char *&gt; make_type_name()
  {
      const char * prefix = std::is_signed_v&lt;T&gt; ? "int" : "uint";
      return prefix; // how to concatenate prefix with get_arithmetic_size&lt;T&gt;() ?
  }
  
  static_assert(strings_equal(make_type_name&lt;int&gt;, make_type_name&lt;int32_t&gt;);
  </code></pre>
  
  <p>The code makes compiler-independent string identifier of an arithmetic type.</p>
  
  <p><strong>EDIT1:</strong></p>
  
  <p>A little bit more complicated example is:</p>
  
  <pre><code>template&lt;typename Test, template&lt;typename...&gt; class Ref&gt;
  struct is_specialization : std::false_type {};
  
  template&lt;template&lt;typename...&gt; class Ref, typename... Args&gt;
  struct is_specialization&lt;Ref&lt;Args...&gt;, Ref&gt; : std::true_type {};
  
  template &lt;class T&gt;
  constexpr std::enable_if_t&lt;is_specialization&lt;T, std::vector&gt;::value || is_specialization&lt;T, std::list&gt;::value, const char *&gt; make_type_name()
  {
      return "sequence"; // + make_type_name&lt;typename T::value_type&gt;;
  }
  
  static_assert(strings_equal(make_type_name&lt;std::vector&lt;int&gt;&gt;(), make_type_name&lt;std::list&lt;int&gt;&gt;()));
  </code></pre>