función hash constexpr
Sep 01 2020
Aquí hay una constexprfunción hash, que empaquetará una cadena en el tipo integral sin firmar más grande disponible. ¿Entonces, qué piensas?
#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
Respuestas
3 G.Sliepen Sep 02 2020 at 00:44
Tu código es demasiado complejo. Con C ++ 17, puede escribir funciones constexpr más complejas, por lo que no necesita los trucos de la plantilla 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;
}
Aparte de eso, ¡esta es una función de hash terrible! La salida está altamente correlacionada con la entrada. También solo se cifrará en sizeof(T)caracteres, por lo que las cadenas largas con un prefijo común podrían obtener el mismo valor hash.