使用std::bit_cast:
Try it online!
#include <bit>
#include <array>
#include <cstdint>
#include <iostream>
int main() {
uint64_t x = 0x12345678'87654321ULL;
// Convert one u64 -> two u32
auto v = std::bit_cast<std::array<uint32_t, 2>>(x);
std::cout << std::hex << v[0] << " " << v[1] << std::endl;
// Convert two u32 -> one u64
auto y = std::bit_cast<uint64_t>(v);
std::cout << std::hex << y << std::endl;
}
输出:
87654321 12345678
1234567887654321
std::bit_cast 仅在 C++20 中可用。在 C++20 之前,您可以手动实现 std::bit_cast 到 std::memcpy,但有一个例外是这种实现不像 C++20 变体那样 constexpr:
template <class To, class From>
inline To bit_cast(From const & src) noexcept {
//return std::bit_cast<To>(src);
static_assert(std::is_trivially_constructible_v<To>,
"Destination type should be trivially constructible");
To dst;
std::memcpy(&dst, &src, sizeof(To));
return dst;
}
对于这种特定的整数情况,非常理想的做法是进行位移/或算术以将一个 u64 转换为两个 u32 并再次返回。 std::bit_cast 更通用,支持任何可简单构造的类型,尽管 std::bit_cast 解决方案应该与具有高级优化的现代编译器上的位算术相同。
位算术的一个额外好处是它可以正确处理字节序,它与字节序无关,不像std::bit_cast。
Try it online!
#include <cstdint>
#include <iostream>
int main() {
uint64_t x = 0x12345678'87654321ULL;
// Convert one u64 -> two u32
uint32_t lo = uint32_t(x), hi = uint32_t(x >> 32);
std::cout << std::hex << lo << " " << hi << std::endl;
// Convert two u32 -> one u64
uint64_t y = (uint64_t(hi) << 32) | lo;
std::cout << std::hex << y << std::endl;
}
输出:
87654321 12345678
123456788765432
注意! 作为@Jarod42 points out,位移解决方案不等同于memcpy/bit_cast 解决方案,它们的等价性取决于字节序。在小端 CPU 上 memcpy/bit_cast 给出最低有效一半 (lo) 作为数组元素 v[0] 和最重要 (hi) 在 v[1] 中,而在大端上最低有效 (lo) 到 v[1] 和最重要的是v[0]。虽然位移解决方案与字节序无关,并且在所有系统上都将最高有效一半 (hi) 设为 uint32_t(num_64 >> 32),将最低有效一半 (lo) 设为 uint32_t(num_64)。