如何为Boost中的SumPoint结构体添加归档版本信息?
解决Boost序列化版本号添加错误的问题
错误原因
出现'boost::serialization::version': 'SumPoint' is not a valid template type argument错误的核心原因是**BOOST_CLASS_VERSION宏被放在了SumPoint结构体定义之前**。此时编译器尚未完成SumPoint的类型定义,无法识别它作为模板参数的合法性。
修复步骤
1. 调整版本号宏的位置
将BOOST_CLASS_VERSION(SumPoint, 1)移动到SumPoint结构体定义的末尾之后,确保编译器已经完整解析了SumPoint类型:
struct SumPoint { SumPoint() = default; explicit SumPoint(float val) : x{ val }, y{ val }, z{ val } {} SumPoint(float X, float Y, float Z) : x{ X }, y{ Y }, z{ Z } {} SumPoint(float X, float Y, float Z, bool _isSmooth) : x{ X }, y{ Y }, z{ Z }, isSmooth{ _isSmooth }{} float x{ 0.0f }; float y{ 1.0f }; float z{ 1.0f }; bool isSmooth{ false }; SumPoint& operator = (const SumPoint& point) { x = point.x; y = point.y; z = point.z; isSmooth = point.isSmooth; return *this; } SumPoint operator + (const SumPoint& point) { SumPoint poi; poi.x = x + point.x; poi.y = y + point.y; poi.z = z + point.z; return poi; } SumPoint operator - (const SumPoint& point) { SumPoint poi; poi.x = x - point.x; poi.y = y - point.y; poi.z = z - point.z; return poi; } bool operator == (const SumPoint& point) { return x == point.x && y == point.y && z == point.z && isSmooth == point.isSmooth; } bool operator != (const SumPoint& point) { return x != point.x || y != point.y || z != point.z || isSmooth != point.isSmooth;} void SetPoint(float X, float Y, float Z) { x = X ; y = Y ; z = Z; } SumPoint& rotL90(unsigned char axis) { float f; switch (toupper(axis)) { case 'X': f = z; z = -y; y = f; break; case 'Y': f = z; z = -x; x = f; break; case 'Z': f = y; y = -x; x = f; break; } return *this; } void normalize() { float length = sqrt((x * x) + (y * y) + (z * z)); x = x / length; y = y / length; z = z / length; } float Distance(SumPoint p) { return std::sqrt(powf( p.x - x , 2) + pow( p.y - y , 2) + pow(p.z - z , 2)); } glm::vec2 ToGlmVector() { return glm::vec2(x, y); } friend class boost::serialization::access; template<class Archive> void save(Archive & ar, const unsigned int version) const { ar & x & y & z; // 版本升级示例:若版本>=2则保存isSmooth if (version >= 2) { ar & isSmooth; } } template<class Archive> void load(Archive& ar, const unsigned int version) { ar & x & y & z; // 版本升级示例:根据版本决定是否读取isSmooth if (version >= 2) { ar & isSmooth; } else { isSmooth = false; } } BOOST_SERIALIZATION_SPLIT_MEMBER() }; // 将版本号宏移至结构体定义之后 BOOST_CLASS_VERSION(SumPoint, 1)
2. 额外修正:运算符重载逻辑错误
原代码中operator!=的判断逻辑存在错误,isSmooth == point.isSmooth应改为isSmooth != point.isSmooth,否则会导致不等判断结果异常,已在上述代码中修正。
3. 版本升级兼容性处理示例
如果后续需要给SumPoint添加新字段(比如当前的isSmooth),可按以下步骤保证兼容性:
- 将版本号宏更新为
BOOST_CLASS_VERSION(SumPoint, 2) - 在
save函数中判断版本>=2时保存新字段 - 在
load函数中根据版本号决定是否读取新字段,旧版本数据则使用默认值初始化新字段
这样旧版本的序列化数据仍能被正确加载,避免兼容性问题。
内容的提问来源于stack exchange,提问作者Summit
相关产品推荐
相关产品推荐

