如何解决Boost序列化以结构体为键的map时的编译错误?
解决Boost序列化自定义结构体作为std::map键值的编译错误
这个编译错误的核心原因很清晰:Boost序列化框架要求所有要被序列化的自定义类型必须提供serialize方法,但你的MyKey和MyValue结构体完全没实现这部分逻辑,导致Boost的序列化代码找不到对应成员函数抛出错误。
具体修复步骤
- 为
MyKey和MyValue结构体添加serialize成员函数,定义如何序列化/反序列化结构体的成员变量 - 声明
boost::serialization::access为友元,确保Boost序列化库可以访问这个方法(即使你把serialize设为私有)
修改后的完整代码
#include <ros/ros.h> #include <map> #include <fstream> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/map.hpp> #include <boost/serialization/access.hpp> // 确保包含这个头文件 int main (int argc, char** argv) { ros::init (argc, argv, "training"); ros::NodeHandle nh; struct MyKey { int d0, d1, d2, a0, b0, a1, b1, a2, b2; bool operator < (const MyKey& o) const { return std::tie(d0, d1, d2, a0, b0, a1, b1, a2, b2) < std::tie(o.d0, o.d1, o.d2, o.a0, o.b0, o.a1, o.b1, o.a2, o.b2); } private: // 声明序列化访问类为友元 friend class boost::serialization::access; // 序列化方法,Boost会自动调用这个函数 template<class Archive> void serialize(Archive & ar, const unsigned int version) { // 依次序列化所有成员变量 ar & d0; ar & d1; ar & d2; ar & a0; ar & b0; ar & a1; ar & b1; ar & a2; ar & b2; } }; struct MyValue { int p0, p1, p2; private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & p0; ar & p1; ar & p2; } }; std::map<MyKey, MyValue> pobj; std::ofstream s("obj_pattern"); boost::archive::text_oarchive oa(s); // 优化点:先完成所有插入操作,再序列化整个map,避免重复序列化冗余数据 for(int i=0;i<5000000;i++) { pobj.insert({{i, i+1, i+2, i+3, i+4, i+5, i+6, i+7, i+8}, {i+9, i+10, i+11}}); } oa << pobj; return 0; }
额外说明
- 序列化方法的作用:
serialize是Boost序列化的核心,它告诉框架如何将结构体成员写入归档(序列化)或从归档读取(反序列化)。模板参数Archive兼容输出/输入归档类型,同一个方法能同时处理两种操作。 - 友元声明的必要性:把
serialize设为私有是最佳实践,通过友元让Boost的access类专属访问,避免这个方法被其他代码误调用。 - 代码优化:你原本的代码在每次循环都序列化整个
pobj,会重复写入大量冗余数据,效率极低。修改后先完成所有插入再一次性序列化,才是合理的用法。
内容的提问来源于stack exchange,提问作者Dinesh Lama
相关产品推荐
相关产品推荐

