如何创建引用uint32的uint64,使其算术操作同步更新高低位变量?
实现64位值与两个32位变量的双向同步更新
现有代码如下:
auto lo = 0u; auto hi = 1u; auto combined = (((std::uint64_t)hi) << 32) | lo;执行
combined++后,lo和hi的值不会改变,因为combined是二者的副本。需要让combined的低32位关联lo、高32位关联hi,使得对combined进行算术操作时,lo和hi能同步更新。
方法1:自定义封装类(最安全可靠)
通过封装类持有lo和hi的引用,重载算术运算符实现双向同步,完全符合C++标准,无未定义行为:
#include <cstdint> class Combined64 { private: std::uint32_t& lo_; std::uint32_t& hi_; public: Combined64(std::uint32_t& lo, std::uint32_t& hi) : lo_(lo), hi_(hi) {} // 转换为uint64_t用于读取当前组合值 operator std::uint64_t() const { return (static_cast<std::uint64_t>(hi_) << 32) | lo_; } // 前缀自增 Combined64& operator++() { std::uint64_t val = static_cast<std::uint64_t>(*this); val++; hi_ = static_cast<std::uint32_t>(val >> 32); lo_ = static_cast<std::uint32_t>(val & 0xFFFFFFFF); return *this; } // 后缀自增 Combined64 operator++(int) { Combined64 temp = *this; ++(*this); return temp; } // 按需重载其他算术运算符,比如加法赋值 Combined64& operator+=(std::uint64_t rhs) { std::uint64_t val = static_cast<std::uint64_t>(*this); val += rhs; hi_ = static_cast<std::uint32_t>(val >> 32); lo_ = static_cast<std::uint32_t>(val & 0xFFFFFFFF); return *this; } }; // 使用示例 int main() { std::uint32_t lo = 0u; std::uint32_t hi = 1u; Combined64 combined(lo, hi); combined++; // 此时lo=1,hi=1 combined += 0xFFFFFFFE; // 此时lo=0xFFFFFFFF,hi=1 combined++; // 此时lo=0,hi=2 return 0; }
方法2:使用union(依赖编译器扩展)
C++标准中访问union非活跃成员属于未定义行为,但GCC、Clang等主流编译器支持该用法作为扩展:
#include <cstdint> union Dual32To64 { struct { std::uint32_t lo; std::uint32_t hi; } parts; std::uint64_t combined; }; // 使用示例 int main() { Dual32To64 val; val.parts.lo = 0u; val.parts.hi = 1u; val.combined++; // 此时val.parts.lo=1,val.parts.hi=1 return 0; }
注意:该写法移植性差,仅适合特定编译器环境,生产环境谨慎使用。
方法3:位域结构体(存在可移植性风险)
位域的内存布局由编译器决定,端序不同可能导致高低位反转,且强制类型转换属于未定义行为:
#include <cstdint> struct Dual32To64 { std::uint32_t lo : 32; std::uint32_t hi : 32; }; // 使用示例 int main() { Dual32To64 val{0u, 1u}; auto* combined = reinterpret_cast<std::uint64_t*>(&val); (*combined)++; // 此时val.lo=1,val.hi=1(仅在小端序且编译器位域布局符合预期时生效) return 0; }
注意:该写法依赖平台和编译器实现,跨平台场景不推荐。
内容的提问来源于stack exchange,提问作者Wirable2323
相关产品推荐
相关产品推荐

