ฟังก์ชันแฮช constexpr
Sep 01 2020
นี่คือconstexprฟังก์ชันแฮชที่จะรวมสตริงไว้ในประเภทอินทิกรัลที่ไม่ได้ลงชื่อที่ใหญ่ที่สุดที่มีอยู่ ดังนั้นสิ่งที่คุณคิดว่า?
#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
คำตอบ
3 G.Sliepen Sep 02 2020 at 00:44
รหัสของคุณซับซ้อนเกินไป ด้วย C ++ 17 คุณสามารถเขียนฟังก์ชัน constexpr ที่ซับซ้อนมากขึ้นได้ดังนั้นคุณจึงไม่จำเป็นต้องใช้เทคนิคแม่แบบที่หลากหลาย:
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;
}
นอกเหนือจากนั้นนี่เป็นฟังก์ชันแฮชที่แย่มาก! เอาต์พุตมีความสัมพันธ์อย่างมากกับอินพุต นอกจากนี้ยังแฮชได้ไม่เกินsizeof(T)อักขระดังนั้นสตริงแบบยาวที่มีคำนำหน้าทั่วไปทั้งหมดอาจได้รับค่าแฮชเหมือนกัน