I'm using the cereal library to serialize my classes into files, but am running into trouble with std::map
- specifically, maps that use std::filesystem::path
.
Say I have an Object
class that contains only a map<fs::path, fs::path>
, as well as the required serialize function for cereal:
struct Object
{
map<fs::path, fs::path> _map;
template<class Archive>
void serialize(Archive & archive)
{
archive(_map);
}
friend ostream& operator<<(ostream& outs, const Object c)
{
for (auto const &pair: c._map)
std::cout << "{" << pair.first << ": " << pair.second << "}\n";
return outs;
}
};
In my main function, I have:
int main()
{
// create Object
cout << "Creating object..." << endl;
Object o;
fs::path a = "bye.txt";
fs::path b = "hello.txt";
o._map[a] = b;
o._map[b] = a;
cout << "Object created: " << endl;
cout << o;
// serialize
cout << "Serializing object...." << endl;
stringstream ss;
cereal::BinaryOutputArchive oarchive(ss);
oarchive(o);
cout << "Object serialized." << endl;
// write to file
cout << "Writing serialized object to file...." << endl;
ofstream file("serialized_object");
file << ss.str();
file.close();
cout << "Object written to file." << endl;
// read from file
cout << "Reading from file..." << endl;
stringstream ss2;
fs::path ins = "serialized_object";
ifstream file_stream(ins, ios::binary);
ss2 << file_stream.rdbuf();
cereal::BinaryInputArchive iarchive(ss2);
Object out;
iarchive(out);
cout << "Object read from file." << endl;
cout << out;
}
In my output, I see the error when it reads from the serialized file:
Creating object...
Object created:
{"bye.txt": "hello.txt"}
{"hello.txt": "bye.txt"}
Serializing object....
Object serialized.
Writing serialized object to file....
Object written to file.
Reading from file...
terminate called after throwing an instance of 'cereal::Exception'
what(): Failed to read 2573 bytes from input stream! Read 28
My includes are:
#include <iostream>
#include <filesystem>
#include <fstream>
#include <string.h>
#include <map>
#include "cereal/types/map.hpp"
#include "cereal/archives/binary.hpp"
#include "cereal/types/string.hpp"
And I have included the following code at the beginning in order to be able to serialize fs::path
:
namespace std
{
namespace filesystem
{
template<class Archive>
void CEREAL_LOAD_MINIMAL_FUNCTION_NAME(const Archive&, path& out, const string& in)
{
out = in;
}
template<class Archive>
string CEREAL_SAVE_MINIMAL_FUNCTION_NAME(const Archive& ar, const path& p)
{
return p.string();
}
}
}
I'm sure I'm missing something obvious, as this is my first time using cereal. Does anyone have any insight as to why I'm running into this issue?