帮自己一个忙,整理一下你的类型:
using Layer = std::unordered_map<key_type, value_type, key_hash>;
using forward_flow_type = std::unordered_map<time_type, Layer>;
const 被误导了,这取决于容器实现。
接下来,
void deserialize_layer(int t) const
标记为const,但你...
m_forward_flow.emplace(t, forward_layer);
这不会编译。所以,去掉 const。
剩下的问题是您的密钥类型不是默认可构造的。最简单的方法是添加:
key_type(coord_type const& origin = {},
coord_type const& destination = {})
: from(origin)
, to(destination)
{
}
复杂的方法是使用save_construct_data and load_construct_data实现序列化。
演示
这增加了足够的机器来完成一个充满演示数据的单帧的往返:
Live On Coliru
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/functional/hash.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/unordered_map.hpp>
#include <boost/serialization/utility.hpp>
#include <fstream>
#include <iostream>
#include <unordered_map>
auto get_forward_flow_archive_name(int t)
{
return "forward_flow_" + std::to_string(t) + ".dat";
}
struct another_serializable_and_tested_class {
double x, y;
void serialize(auto& ar, unsigned) { ar & x & y; }
bool operator==(another_serializable_and_tested_class const&) const = default;
friend size_t hash_value(another_serializable_and_tested_class const& o) {
auto h = boost::hash_value(o.x);
boost::hash_combine(h, boost::hash_value(o.y));
return h;
}
friend std::ostream& operator<<(std::ostream& os, another_serializable_and_tested_class const& p)
{
return os << "(" << p.x << ", " << p.y << ")";
}
};
template <typename A, typename B, typename C> class MyClass {
public:
using coord_type = another_serializable_and_tested_class;
struct key_type {
coord_type from;
coord_type to;
key_type(coord_type const& origin = {},
coord_type const& destination = {})
: from(origin)
, to(destination)
{
}
bool operator==(key_type const& other) const
{
return (other.from == this->from && other.to == this->to);
}
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar& from;
ar& to;
}
}; // end struct key_type
struct key_hash {
std::size_t operator()(const key_type& k) const
{
size_t res = 17;
boost::hash_combine(res, k.from);
boost::hash_combine(res, k.to);
return res;
}
}; // end struct key_hash
using time_type = int; // stub
using value_type = long; // stub
using Layer = std::unordered_map<key_type, value_type, key_hash>;
using forward_flow_type = std::unordered_map<time_type, Layer>;
forward_flow_type m_forward_flow;
// other members and functions, including the serialization/deserialization
// operations:
void serialize_layer(int t) const
{
const std::string forward_filename = get_forward_flow_archive_name(t);
std::ofstream forward_ofs(forward_filename, std::ios::binary);
boost::archive::binary_oarchive forward_oa(forward_ofs);
forward_oa << m_forward_flow.at(t);
}
// other members and functions, including the serialization/deserialization
// operations:
void deserialize_layer(int t)
{
const std::string forward_filename = get_forward_flow_archive_name(t);
// create and open an archive for input
std::ifstream forward_ifs(forward_filename, std::ios::binary);
boost::archive::binary_iarchive forward_ia(forward_ifs);
// read class state from archive
Layer forward_layer;
forward_ia >> forward_layer;
// archive and stream closed when destructors are called
m_forward_flow.emplace(t, forward_layer);
}
};
int main() {
using Object = MyClass<void, void, void>;
{
Object obj;
auto& layer42 = obj.m_forward_flow.emplace(42, Object::Layer{}).first->second;
for (auto& [k, v] : {
std::tuple(
Object::key_type{
{1, 2}, // from
{3, 4} // to
},
5),
std::tuple(Object::key_type{{6, 7}, {8, 9}}, 10),
std::tuple(Object::key_type{{11, 12}, {13, 14}}, 15),
std::tuple(Object::key_type{{16, 17}, {18, 19}}, 20),
std::tuple(Object::key_type{{21, 22}, {23, 24}}, 25),
std::tuple(Object::key_type{{26, 27}, {28, 29}}, 30),
})
{
layer42.emplace(k, v);
}
obj.serialize_layer(42);
}
{
Object obj;
obj.deserialize_layer(42);
for (auto& [k, v] : obj.m_forward_flow.at(42)) {
auto& [from,to] = k;
std::cout << "From " << from << " to " << to << " value " << v << "\n";
}
}
}
打印
From (1, 2) to (3, 4) value 5
From (6, 7) to (8, 9) value 10
From (11, 12) to (13, 14) value 15
From (16, 17) to (18, 19) value 20
From (21, 22) to (23, 24) value 25
From (26, 27) to (28, 29) value 30
正如预期的那样。该文件(在我的机器上)包含:
00000000: 1600 0000 0000 0000 7365 7269 616c 697a ........serializ
00000010: 6174 696f 6e3a 3a61 7263 6869 7665 0f00 ation::archive..
00000020: 0408 0408 0100 0000 0000 0000 0006 0000 ................
00000030: 0000 0000 000d 0000 0000 0000 0000 0000 ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000050: 0000 0000 0000 3a40 0000 0000 0000 3b40 ......:@......;@
00000060: 0000 0000 0000 3c40 0000 0000 0000 3d40 ......<@......=@
00000070: 1e00 0000 0000 0000 0000 0000 0000 3540 ..............5@
00000080: 0000 0000 0000 3640 0000 0000 0000 3740 ......6@......7@
00000090: 0000 0000 0000 3840 1900 0000 0000 0000 ......8@........
000000a0: 0000 0000 0000 3040 0000 0000 0000 3140 ......0@......1@
000000b0: 0000 0000 0000 3240 0000 0000 0000 3340 ......2@......3@
000000c0: 1400 0000 0000 0000 0000 0000 0000 2640 ..............&@
000000d0: 0000 0000 0000 2840 0000 0000 0000 2a40 ......(@......*@
000000e0: 0000 0000 0000 2c40 0f00 0000 0000 0000 ......,@........
000000f0: 0000 0000 0000 1840 0000 0000 0000 1c40 .......@.......@
00000100: 0000 0000 0000 2040 0000 0000 0000 2240 ...... @......"@
00000110: 0a00 0000 0000 0000 0000 0000 0000 f03f ...............?
00000120: 0000 0000 0000 0040 0000 0000 0000 0840 .......@.......@
00000130: 0000 0000 0000 1040 0500 0000 0000 0000 .......@........