hàm băm constexpr
Sep 01 2020
Đây là một constexprhàm băm, sẽ đóng gói một chuỗi thành kiểu tích phân không dấu lớn nhất hiện có. Vậy bạn nghĩ như thế nào?
#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
Trả lời
3 G.Sliepen Sep 02 2020 at 00:44
Mã của bạn quá phức tạp. Với C ++ 17, bạn có thể viết các hàm constexpr phức tạp hơn, vì vậy bạn không cần các thủ thuật tạo mẫu đa dạng:
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;
}
Ngoài ra, đây là một hàm băm khủng khiếp! Đầu ra có tương quan cao với đầu vào. Nó cũng sẽ chỉ băm tối đa các sizeof(T)ký tự, vì vậy các chuỗi dài có tiền tố chung đều có thể nhận được cùng một giá trị băm.