c++的提升.使用自定义对象作为键的hash_map序列化错误
C++ Boost.Serialization error for hash_map with custom objects as key
我需要序列化一个对象,它包含一个hash_map,另一个对象作为键。用作键的对象是其他对象的基类。我已经在基类和派生类中实现了serialize()方法,每个派生类都继承了基类的序列化方法。情况类似如下:
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/hash_map.hpp>
#include <boost/serialization/base_object.hpp>
class Item {
protected:
unsigned int _refc;
static unsigned int _total_alloc;
//other code
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & _refc;
ar & _total_alloc;
}
};
class StringItem : public Item {
private:
string _s;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & boost::serialization::base_object<Item>(*this);
ar & _s;
}
};
这是我需要序列化的类:
class TokenFinder : public Model {
public:
TokenFinder(void);
virtual ~TokenFinder(void);
virtual void insert_item(Item *item);
private:
/** Map to store tokens together with their number of occurrences.
*/
__gnu_cxx::hash_map<Item *, unsigned long> _elements;
unsigned long _element_count;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & _elements; //Error when saved
ar & _element_count;
}
};
当我尝试序列化TokenFinder对象时,错误是:在抛出'boost::archive::archive_exception'实例后调用终止
有什么建议吗?提前感谢!
尝试在使用前向Archive注册Item的子类:
template<class Archive>
void serialize(Archive & ar, unsigned)
{
ar.template register_type<StringItem>(); // THIS
ar & boost::serialization::base_object<Model>(*this);
ar & _elements;
ar & _element_count;
}
查看Live demo On Coliru
输出22 serialization::archive 10 0 0 0 0 0 0 6 0 0 0 1 1 0
0 1 0
1 0 10 cow-jumped 6 1
2
3 0 4 moon 5 1
4
5 0 4 lazy 4 1
6
7 0 3 the 3 1
8
9 0 5 world 2 1
10
11 0 5 hello 1 0
指出- 我为
std::unordered_map
定义了序列化,所以你不再需要使用废弃的GNU库扩展(另见此bug-report/patch) - 我注释掉了
_total_alloc
,因为,当然,你不希望这个数字反序列化 - 我离开了管理
Item
s的生命周期/分配作为一个练习(我不知道你想要的所有权语义组织)
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <unordered_map>
#include <boost/serialization/collections_save_imp.hpp>
#include <boost/serialization/collections_load_imp.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/split_free.hpp>
namespace boost { namespace serialization {
template<class Archive, typename... TArgs >
inline void save(Archive & ar, std::unordered_map<TArgs...> const&t, unsigned) {
boost::serialization::stl::save_collection<Archive, std::unordered_map<TArgs...> >(ar, t);
}
template<class Archive, typename... TArgs >
inline void load(Archive & ar, std::unordered_map<TArgs...> &t, unsigned) {
boost::serialization::stl::load_collection<Archive,
std::unordered_map<TArgs...>,
boost::serialization::stl::archive_input_map<
Archive, std::unordered_map<TArgs...> >,
boost::serialization::stl::no_reserve_imp<std::unordered_map<TArgs...> >
>(ar, t);
}
// split non-intrusive serialization function member into separate
// non intrusive save/load member functions
template <class Archive, typename... TArgs>
inline void serialize(Archive & ar, std::unordered_map<TArgs...> &t, unsigned file_version) {
boost::serialization::split_free(ar, t, file_version);
}
} }
#include <boost/serialization/base_object.hpp>
class StringItem;
class Item {
protected:
unsigned int _refc;
static unsigned int _total_alloc;
//other code
Item() : _refc(0) { }
virtual ~Item() {}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, unsigned)
{
ar & _refc;
//ar & _total_alloc; // wut? a static?!
}
};
/*static*/ unsigned int Item::_total_alloc;
class StringItem : public Item {
public:
StringItem(std::string s = "") : _s(std::move(s)) { }
private:
std::string _s;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, unsigned)
{
ar & boost::serialization::base_object<Item>(*this);
ar & _s;
}
};
struct Model {
virtual ~Model() {}
template<class Archive> void serialize(Archive&r, unsigned) { }
};
class TokenFinder : public Model
{
public:
TokenFinder(void) : _element_count(0) {}
virtual ~TokenFinder(void) {}
virtual void insert_item(Item *item) { _elements[item] = _elements.size()+1; }
private:
/** Map to store tokens together with their number of occurrences. */
std::unordered_map<Item*, unsigned long> _elements;
unsigned long _element_count;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, unsigned)
{
ar.template register_type<StringItem>();
ar & boost::serialization::base_object<Model>(*this);
ar & _elements;
ar & _element_count;
}
};
int main()
{
boost::archive::text_oarchive oa(std::cout);
std::vector<StringItem> seed_data {
{"hello"},{"world"},{"the"},{"lazy"},{"moon"}, {"cow-jumped"}
};
TokenFinder tf;
for(auto& si : seed_data)
tf.insert_item(&si);
oa << tf;
}
相关文章:
- 如何在C++中序列化结构数据
- 序列化,没有库的整数,得到奇怪的结果
- 如何知道QDataStream不能反序列化某些内容
- 如何使用Python从C++中读取谷物序列化数据
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 自定义对象的dlib序列化在gcc中失败
- C++boost序列化多态性问题
- 增强基于 XML class_id的反序列化
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 每次进行继承时都需要提升::序列化::base_object吗?
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 提升序列化 1:73 的向后兼容性问题
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 如何反序列化数组?
- 如何使用提升序列化?
- 序列化多晶型接口
- FlatBuffers/Protobuf 中是否有支持任意 24 位有符号整数定义的可移植二进制序列化架构?