constexpr hash function Here's a constexpr hash function, that will pack a string into the largest unsigned integral type available. So, what do you think?
#include &lt;climits&gt;

#include &lt;cstdint&gt;

#include &lt;utility&gt;

#include &lt;iostream&gt;

namespace detail
{

template &lt;typename T, std::size_t ...I&gt;
constexpr T hash(char const* const s, std::size_t const N,
  std::index_sequence&lt;I...&gt;) noexcept
{
  return ((T(s[I &lt; N ? I : 0]) &lt;&lt; ((I &lt; N ? I : 0) * CHAR_BIT)) | ...);
}

}

template &lt;typename T = std::uintmax_t&gt;
constexpr T hash(char const* const s, std::size_t const N) noexcept
{
  return detail::hash&lt;T&gt;(s, N, std::make_index_sequence&lt;sizeof(T)&gt;());
}

template &lt;typename T = std::uintmax_t, std::size_t N&gt;
constexpr T hash(char const(&amp;s)[N]) noexcept
{
  return hash&lt;T&gt;(s, N - 1);
}

int main()
{
  std::cout &lt;&lt; (hash(&quot;a&quot;) == 'a') &lt;&lt; std::endl;

  return 0;
}

https://wandbox.org/permlink/KbPiWJc434xYLL3q
Your code is too complex. With C++17, you can write more complex constexpr functions, so you don't need the variadic template tricks:
template &lt;typename T = std::uintmax_t, std::size_t N&gt;
constexpr T hash(char const(&amp;s)[N]) noexcept
{
  T val{};

  for (size_t i = 0; i &lt; N; ++i)
    val |= s[i] &lt;&lt; (i * CHAR_BIT);

  return val;
}

Apart from that, this is a terrible hash function! The output is highly correlated to the input. It will also only hash up to sizeof(T) characters, so long strings with a common prefix might all get the same hash value.