fungsi hash constexpr

Sep 01 2020

Berikut adalah constexprfungsi hash, yang akan mengemas string ke dalam tipe integral unsigned terbesar yang tersedia. Jadi apa yang Anda pikirkan?

#include <climits>

#include <cstdint>

#include <utility>

#include <iostream>

namespace detail
{

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

}

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

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

int main()
{
  std::cout << (hash("a") == 'a') << std::endl;

  return 0;
}

https://wandbox.org/permlink/KbPiWJc434xYLL3q

Jawaban

3 G.Sliepen Sep 02 2020 at 00:44

Kode Anda terlalu rumit. Dengan C ++ 17, Anda dapat menulis fungsi constexpr yang lebih kompleks, jadi Anda tidak memerlukan trik template variadic:

template <typename T = std::uintmax_t, std::size_t N>
constexpr T hash(char const(&s)[N]) noexcept
{
  T val{};

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

  return val;
}

Selain itu, ini adalah fungsi hash yang buruk! Output sangat berkorelasi dengan input. Itu juga hanya akan sizeof(T)mencirikan hingga karakter, jadi string yang panjang dengan awalan umum mungkin semua mendapatkan nilai hash yang sama.