'Boost serialization of interface map
I have created a map of multiple different data types. s64, f64, Arrays, Images, etc.
To do so, i used a map of type std::map<std::string, std::unique_ptr<MapEntryInterface>> database;.
I want to store it, and reload it from filesystem. But i heard that maps cant be sored in a one-liner. So i tried to store the data part std::unique_ptr<MapEntryInterface> test; of one pair first:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, unsigned int version) {
ar & test;
}
The program crashes at ar & test throwing an exception: "unregistered class - derived class not registered or exported".
whats the issue? i dont understand it.
here is the minimal code: (deleted)
#include <boost/serialization/vector.hpp>
//....
};
as 463035818_is_not_a_number pointed out, my sniped is not working.
i recreated it, and got a lot further i think. But as soon as i insert the load from file function, it does not compile anymore saying:
error C2280: "std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)" : Es wurde versucht, auf eine gelöschte Funktion zu verweisen
#include <boost/serialization/vector.hpp>
#include <boost/serialization/unique_ptr.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>
#include <iostream>
class MapEntryInterface {
public:
MapEntryInterface(std::string type_str) : type(type_str) {}
std::string type;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, unsigned int version) {
if (type == "s64") {
MapEntryS64* cast = (MapEntryS64*)this;
cast->serialize(ar, version);
}
if (type == "f64") {
MapEntryF64* cast = (MapEntryF64*)this;
cast->serialize(ar, version);
}
}
};
class MapEntryS64 : public MapEntryInterface {
public:
MapEntryS64(int init_val, const std::string& type_str)
: data(init_val), MapEntryInterface(type_str)
{}
uint64_t data;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, unsigned int version) {
ar & type;
ar & data;
}
};
class MapEntryF64 : public MapEntryInterface {
public:
MapEntryF64(double init_val, const std::string& type_str)
: data(init_val), MapEntryInterface(type_str)
{}
double data;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, unsigned int version) {
ar & type;
ar & data;
}
};
class MapDataBase {
public:
MapDataBase()
//: test(std::unique_ptr<MapEntryInterface>(new MapEntryS64(381, "s64")))
{
database["key1"] = std::unique_ptr<MapEntryInterface>(new MapEntryS64(381, "s64"));
database["key2"] = std::unique_ptr<MapEntryInterface>(new MapEntryF64(3.124512, "f64"));
};
bool SaveToFile() {
std::ofstream ofs("boost_export.dat");
if (ofs.is_open()) {
boost::archive::text_oarchive oa(ofs);
oa & *this;
return true;
}
return false;
}
bool loadFromFile() {
std::ifstream ifs("boost_export.dat");
if (ifs.is_open())
{
try
{
boost::archive::text_iarchive ia(ifs);
ia & *this;
//std::string yolo;
//ia >> yolo;
//ia >> bam;
}
catch (std::exception& ex)
{
std::cout << ex.what() << std::endl;
return false;
}
}
return true;
}
private:
std::map<std::string, std::unique_ptr<MapEntryInterface>> database;
//std::unique_ptr<MapEntryInterface> test;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, unsigned int version) {
ar & database;
}
};
void main() {
MapDataBase tmp;
tmp.SaveToFile();
MapDataBase tmp2;
//tmp2.loadFromFile();
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
