This is my json string
{
"connectionString" : "MyConnectionString",
"value" :"MyVal"
}
This is my class
struct Settings
{
std::string connectionString;
std::string value;
template<class Archive>
void serialize(Archive& ar)
{
ar(CEREAL_NVP(connectionString),
CEREAL_NVP(value)
);
}
};
And this is what I am doing:
std::ifstream ifs("Settings.json");
std::string content((std::istreambuf_iterator<char>(ifs)),(std::istreambuf_iterator<char>())); // Yes this is valid - The content gets populated
Settings settings;
{
cereal::JSONInputArchive archive_in(ifs);
archive_in(settings); //<<-----Exception here - Unhandled exception
}
The above solution would works only if my json string was this (i.e) if all the json string was an object of another key.
{
"SomeThing" :{
"connectionString" : "MyConnectionString",
"value" :"MyVal"
}
}
My question is how can I make my actual json string work (without wrapping it in an object)? I currently have this in a json file
{
"connectionString" : "MyConnectionString",
"value" :"MyVal"
}
and I wanted to know the best approach of deserializing this into an object ?
The code expecting that outer object is put there by the default JSON "prologue" and "epilogue" behavior:
From the documentation:
These functions are given a reference to the active archive and a constant reference to the type being serialized. Careful specialization of prologue and epilogue allows for archives to exercise special behaviors without having to re-implement serialization functions for types. This lets us make the type support fairly generic. For example, cereal::XMLOutputArchive (<cereal/archives/xml.hpp>) makes use of these functions to start and finish nodes in its in-memory tree.
If you add in your code an overload for your type that does nothing:
void epilogue(cereal::JSONInputArchive&, const Settings&) { }
void prologue(cereal::JSONInputArchive&, const Settings&) { }
It won't try to parse an outer object