我正在尝试实现一个可以在编译时使用的哈希函数。为了实现这一点,我需要将一个值(例如,int 或 float)重新解释为其原始字节。然而,当使用编译时求值时,由于严格的别名和其他限制,不允许指针类型双关(重新解释)。
这里有一个简化的例子来说明这个问题:
template <typename T>
constexpr size_t hash(const T& value) {
const unsigned char* byte_ptr = reinterpret_cast<const unsigned char*>(&value); // NOT allowed.
size_t hash = 0;
for (size_t i = 0; i < sizeof(T); ++i) {
hash ^= byte_ptr[i];
}
return hash;
}
是否有一种符合标准的方法可以在 constexpr 上下文中将值重新解释为字节?
std::bit_cast
支持constexpr。
您可以使用 bit_cast
到 std::array
,然后使用 std::array::data()
访问字节:
#include <array>
#include <cstddef>
#include <bit>
template <typename T>
constexpr size_t byte_sum(const T& value) {
//const unsigned char* byte_ptr = reinterpret_cast<const unsigned char*>(&value); // NOT allowed.
auto arr = std::bit_cast<std::array<unsigned char, sizeof(value)>>(value);
const unsigned char* byte_ptr = arr.data();
size_t hash = 0;
for (size_t i = 0; i < sizeof(T); ++i) {
hash ^= byte_ptr[i];
}
return hash;
}
int main() {
constexpr double d = 5;
[[maybe_unused]] constexpr size_t h = byte_sum(d);
}