自定义24位有符号整数搭配boost::atomic触发可平凡拷贝报错如何解决
问题原因
boost::atomic要求模板参数类型必须是平凡可拷贝类型,你的自定义Int24类因为显式实现了默认构造函数、拷贝构造函数、拷贝赋值运算符,不满足平凡可拷贝的定义,所以编译报错。
平凡可拷贝类型要求:没有自定义的拷贝/移动构造、拷贝/移动赋值、析构函数,所有非静态成员都是平凡可拷贝的,没有虚函数、虚基类。
解决方案1:改造Int24为平凡可拷贝类型
你只需要将类中手动实现的、和编译器默认行为一致的特殊成员函数改为显式默认即可,其余运算符逻辑完全不需要修改:
#include <type_traits> const int INT24_MAX = 8388607; class Int24 { protected: unsigned char m_Internal[3]; public: // 显式默认构造,满足平凡要求 Int24() = default; Int24(const int val) { *this = val; } // 显式默认拷贝构造,满足平凡要求 Int24(const Int24& val) = default; // 显式默认析构,满足平凡要求 ~Int24() = default; operator int() const { if (m_Internal[2] & 0x80) // 符号位判断,做符号扩展 { return (0xff << 24) | (m_Internal[2] << 16) | (m_Internal[1] << 8) | m_Internal[0]; } else { return (m_Internal[2] << 16) | (m_Internal[1] << 8) | m_Internal[0]; } } operator float() const { return static_cast<float>(this->operator int()); } // 显式默认同类型拷贝赋值,满足平凡要求 Int24& operator =(const Int24& input) = default; Int24& operator =(const int input) { m_Internal[0] = reinterpret_cast<const unsigned char*>(&input)[0]; m_Internal[1] = reinterpret_cast<const unsigned char*>(&input)[1]; m_Internal[2] = reinterpret_cast<const unsigned char*>(&input)[2]; return *this; } // 剩余的运算符逻辑和原实现完全一致,此处省略 }; // 编译期验证是否满足平凡可拷贝要求 static_assert(std::is_trivially_copyable_v<Int24>, "Int24 is not trivially copyable");
改造后即可直接用于boost::atomic<Int24>。
解决方案2:用32位原子变量代理(更稳妥的无锁方案)
大部分主流CPU架构原生不支持3字节长度的无锁原子操作,即使Int24满足平凡可拷贝要求,boost::atomic也可能退化为加锁实现。如果必须保证无锁,可直接用boost::atomic<uint32_t>存储值,对外做Int24转换即可:
// 原子变量定义 boost::atomic<uint32_t> atomic_int24_val; // 写入Int24值 void store(Int24 val) { atomic_int24_val.store(static_cast<int>(val) & 0xffffff, std::memory_order_seq_cst); } // 读取Int24值 Int24 load() { return Int24(static_cast<int>(atomic_int24_val.load(std::memory_order_seq_cst))); }
该方案在所有支持32位无锁原子操作的平台都能达到无锁要求,兼容性更好。
内容的提问来源于stack exchange,提问作者ajspark4444
相关产品推荐
相关产品推荐

