使用boost序列化自定义键的嵌套unordered_map报无serialize成员错误如何解决?
问题原因
你的判断完全正确,问题就是内层unordered_map声明时给键加了顶层const修饰符,和boost::serialization提供的默认unordered_map序列化特化不匹配:
- boost::serialization内置的unordered_map序列化逻辑,仅针对模板参数为
std::unordered_map<Key, T, Hash, KeyEqual, Allocator>(Key无顶层const)的实例提供特化实现 - 你声明的
std::unordered_map<const key_type, value_type, key_hash>属于不同的模板实例,boost找不到对应的serialize函数,因此报出找不到serialize成员的错误
补充说明:你在键模板参数上加的const属于多余写法,std::unordered_map内部存储的元素本身就是std::pair<const Key, T>类型,天然保证键不可修改,额外加const只会改变模板实例类型,不会带来额外的不可修改保障。
额外小提醒:你当前的
deserialize_layer被声明为const成员函数,但内部会修改m_forward_flow成员,需要将m_forward_flow声明为mutable才能正常编译。
解决方案
方案一(推荐):移除键模板参数的const修饰
直接修改两处类型声明即可:
- 修改
forward_flow_type定义:
// 修改前 using forward_flow_type = std::unordered_map<time_type, std::unordered_map<const key_type, value_type, key_hash>>; // 修改后 using forward_flow_type = std::unordered_map<time_type, std::unordered_map<key_type, value_type, key_hash>>;
- 修改
deserialize_layer函数内的forward_layer变量声明:
// 修改前 std::unordered_map<const key_type, value_type, key_hash> forward_layer; // 修改后 std::unordered_map<key_type, value_type, key_hash> forward_layer;
修改后如果出现少量编译错误,都是之前代码冗余依赖键模板参数const导致的,对应修改即可,改造成本远低于其他方案。修改后需确认value_type、time_type都已实现对应的serialize函数,避免后续出现同类报错。
方案二(兼容现有代码):手动补充带const键的unordered_map序列化特化
如果你不想修改现有大量依赖const key_type作为模板参数的代码,可以手动在全局作用域补充boost序列化特化:
#include <boost/serialization/unordered_map.hpp> namespace boost::serialization { template<class Archive, class Key, class T, class Hash, class KeyEqual, class Allocator> void serialize(Archive& ar, std::unordered_map<const Key, T, Hash, KeyEqual, Allocator>& map, const unsigned int version) { // 两种类型内存布局完全一致,直接强转调用现有实现即可 auto& non_const_map = reinterpret_cast<std::unordered_map<Key, T, Hash, KeyEqual, Allocator>&>(map); serialize(ar, non_const_map, version); } }
该特化需要放在所有序列化调用代码之前,且要保证Key类型在特化可见位置已完整定义。
内容的提问来源于stack exchange,提问作者WaterFox
相关产品推荐
相关产品推荐

