Serializing of object with map and multimap. Questions.

I've been having some problems storing and loading a class with a map and a multimap. The map contains values that are simple objects of another class. My questions are below. Here is also a link to the same question posted on stackoverflow. Thanks. http://stackoverflow.com/questions/1676781/boost-serializing-of-object-conta... See below a main() and two very simple classes. Then per Boost serialization (and what is shown) my questions are: 1) Does class B need the normal overloaded stream insertion operators '<<' and '>>' to be defined? Currently in my real code it doesn't have these. 2) Does class A in the store() and load() methods need to iterate through the map and multimap containers explicitly, storing/loading their key:value pairs explicitely? e.g. something like: void A::store(const char* filename){ std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); std::map< std::string, B >::iterator it; BMap.size(); oa << BMap.size(); for( it = BMap.begin(); it != BMap.end(); it++ ){ oa << it->first; oa << it->second; } //similar for strMultimap } I assume that I don't need to do this, but am not certain. 3) Assuming class B has only the two data members shown, does it need a default contructor included explicitely? (as opposed to the implicit default constructor) 4) Does B need to have an overide for the comparison operator '>'? I assume that it doesn't since this is a very simple class. Finally, any other comments per anything that I've failed to cover is appreciated! Example code for my above questions: //includes ommitted int main() { std::string file("test.dat"); A * pA = new A; pA->store(file.c_str()); pA->fillMaps(); //release data pA->load(file.c_str()); return 0; } //includes ommitted class A { friend class boost::serialization::access; public: std::map< std::string, B > BMap; std::multimap< std::string, std::string > strMultimap; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & BMap; ar & strMultimap; } void store(const char* filename){ std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << this; } void load(const char* filename){ std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); ia >> this; } void fillMaps(){ //code to allocate B objects and put them in BMap and fill strMultimap with whatever number of key:value pairs } class B { friend class boost::serialization::access; public: std::string str; unsigned int num; B::B(void) : str("a string") , num(7) { } template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & str; ar & num; } }

I have sent a couple of questions to this list in the past week and haven't
gotten a single response. Wondering if my messages are being bounced???
---------- Forwarded message ----------
From: B Hart

On Thu, Nov 5, 2009 at 1:33 AM, B Hart
I have sent a couple of questions to this list in the past week and haven't gotten a single response. Wondering if my messages are being bounced???
---------- Forwarded message ---------- From: B Hart
Date: Wed, Nov 4, 2009 at 3:42 PM Subject: Serializing of object with map and multimap. Questions. To: Boost-users@lists.boost.org I've been having some problems storing and loading a class with a map and a multimap. The map contains values that are simple objects of another class. My questions are below. Here is also a link to the same question posted on stackoverflow. Thanks.
http://stackoverflow.com/questions/1676781/boost-serializing-of-object-conta...
See below a main() and two very simple classes. Then per Boost serialization (and what is shown) my questions are:
1) Does class B need the normal overloaded stream insertion operators '<<' and '>>' to be defined? Currently in my real code it doesn't have these.
2) Does class A in the store() and load() methods need to iterate through the map and multimap containers explicitly, storing/loading their key:value pairs explicitely? e.g. something like:
void A::store(const char* filename){
std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs);
std::map< std::string, B >::iterator it;
BMap.size(); oa << BMap.size();
for( it = BMap.begin(); it != BMap.end(); it++ ){
oa << it->first; oa << it->second;
}
//similar for strMultimap }
I assume that I don't need to do this, but am not certain.
3) Assuming class B has only the two data members shown, does it need a default contructor included explicitely? (as opposed to the implicit default constructor)
4) Does B need to have an overide for the comparison operator '>'? I assume that it doesn't since this is a very simple class.
Finally, any other comments per anything that I've failed to cover is appreciated!
Example code for my above questions:
//includes ommitted
int main() {
std::string file("test.dat");
A * pA = new A;
pA->store(file.c_str());
pA->fillMaps(); //release data pA->load(file.c_str());
return 0; }
//includes ommitted
class A { friend class boost::serialization::access;
public:
std::map< std::string, B > BMap;
std::multimap< std::string, std::string > strMultimap;
template<class Archive> void serialize(Archive & ar, const unsigned int version)
{ ar & BMap; ar & strMultimap;
}
void store(const char* filename){
std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs);
oa << this; }
void load(const char* filename){
std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs);
ia >> this;
}
void fillMaps(){
//code to allocate B objects and put them in BMap and fill strMultimap with whatever number of key:value pairs
}
class B { friend class boost::serialization::access;
public:
std::string str;
unsigned int num;
B::B(void)
: str("a string") , num(7)
{ }
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{ ar & str; ar & num;
} }
We see your emails. I am not a Boost.Serialization guru though, but let me see if I can help any (take anything I say with a grain of salt, I use Boost.Serialization, but it seems to just 'work' for me most of the time so I do not know much about it): 1) I do not think so, just either an internal or external Boost.Serialization streaming functions as normal. 2) No, Boost.Serialization should already have overloads to handle map's properly, if not then there is plenty of code (and I can post mine that I map for the tr1 maps and set) out there to do that already the 'proper' way. :) 3) You should not need to explicitly create a default constructor, but the class must be default constructable (found that out the hard way). 4) Since you only use B as the data element of a map, no. And the reason you might not be getting responses, you should title your posts appropriately, at the front of you title you should put [Serialization] as many people filter boost email based on the sub library, so you title should have been. [Serialization] Serializing of object with map and multimap. Questions.

OvermindDL1: I'd like to see the sample code you mentioned...thanks.
On Thu, Nov 5, 2009 at 12:44 AM, OvermindDL1
On Thu, Nov 5, 2009 at 1:33 AM, B Hart
wrote: I have sent a couple of questions to this list in the past week and haven't gotten a single response. Wondering if my messages are being bounced???
---------- Forwarded message ---------- From: B Hart
Date: Wed, Nov 4, 2009 at 3:42 PM Subject: Serializing of object with map and multimap. Questions. To: Boost-users@lists.boost.org I've been having some problems storing and loading a class with a map and a multimap. The map contains values that are simple objects of another class. My questions are below. Here is also a link to the same question posted on stackoverflow. Thanks.
http://stackoverflow.com/questions/1676781/boost-serializing-of-object-conta...
See below a main() and two very simple classes. Then per Boost
serialization
(and what is shown) my questions are:
1) Does class B need the normal overloaded stream insertion operators '<<' and '>>' to be defined? Currently in my real code it doesn't have these.
2) Does class A in the store() and load() methods need to iterate through the map and multimap containers explicitly, storing/loading their key:value pairs explicitely? e.g. something like:
void A::store(const char* filename){
std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs);
std::map< std::string, B >::iterator it;
BMap.size(); oa << BMap.size();
for( it = BMap.begin(); it != BMap.end(); it++ ){
oa << it->first; oa << it->second;
}
//similar for strMultimap }
I assume that I don't need to do this, but am not certain.
3) Assuming class B has only the two data members shown, does it need a default contructor included explicitely? (as opposed to the implicit default constructor)
4) Does B need to have an overide for the comparison operator '>'? I assume that it doesn't since this is a very simple class.
Finally, any other comments per anything that I've failed to cover is appreciated!
Example code for my above questions:
//includes ommitted
int main() {
std::string file("test.dat");
A * pA = new A;
pA->store(file.c_str());
pA->fillMaps(); //release data pA->load(file.c_str());
return 0; }
//includes ommitted
class A { friend class boost::serialization::access;
public:
std::map< std::string, B > BMap;
std::multimap< std::string, std::string > strMultimap;
template<class Archive> void serialize(Archive & ar, const unsigned int version)
{ ar & BMap; ar & strMultimap;
}
void store(const char* filename){
std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs);
oa << this; }
void load(const char* filename){
std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs);
ia >> this;
}
void fillMaps(){
//code to allocate B objects and put them in BMap and fill strMultimap with whatever number of key:value pairs
}
class B { friend class boost::serialization::access;
public:
std::string str;
unsigned int num;
B::B(void)
: str("a string") , num(7)
{ }
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{ ar & str; ar & num;
} }
We see your emails. I am not a Boost.Serialization guru though, but let me see if I can help any (take anything I say with a grain of salt, I use Boost.Serialization, but it seems to just 'work' for me most of the time so I do not know much about it):
1) I do not think so, just either an internal or external Boost.Serialization streaming functions as normal.
2) No, Boost.Serialization should already have overloads to handle map's properly, if not then there is plenty of code (and I can post mine that I map for the tr1 maps and set) out there to do that already the 'proper' way. :)
3) You should not need to explicitly create a default constructor, but the class must be default constructable (found that out the hard way).
4) Since you only use B as the data element of a map, no.
And the reason you might not be getting responses, you should title your posts appropriately, at the front of you title you should put [Serialization] as many people filter boost email based on the sub library, so you title should have been.
[Serialization] Serializing of object with map and multimap. Questions. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On Fri, Nov 6, 2009 at 2:13 AM, B Hart
OvermindDL1: I'd like to see the sample code you mentioned...thanks.
I got this for unordered_map, copied from somewhere, but it is the 'proper' way of handling it. You should see how easy it is to change it to handle map or multi_map or what-not.

On Nov 5, 2009, at 12:42 AM, B Hart wrote:
void store(const char* filename){
std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs);
oa << this; }
void load(const char* filename){
std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs);
ia >> this;
}
Don't you mean oa << *this and ia >> *this? I doubt that you want a new object created in load, but rather this object loaded from the file? Matthias

I've noted that if in the load I don't have ia >> *this; then I
get unsupported_class_version when compiling. However, I've also noted that
Store creates nearly identical archive files whether it is:
oa << this;
or
oa << *this;
???
the file stores and loads ok if both are with '*', but I'm unclear as
to why the boost library creates almost identical archives.
The only difference I can tell is one has a newline following the version
info. and one doesn't. I recall it is the one with the newline that then
won't load.
I'll add, the data that is stored is also
still suspect as it does not seem to be having numbers I would expect,
so I'm going to do more checking tomorrow.
On Thu, Nov 5, 2009 at 12:44 AM, Matthias Troyer
On Nov 5, 2009, at 12:42 AM, B Hart wrote:
void store(const char* filename){
std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs);
oa << this; }
void load(const char* filename){
std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs);
ia >> this;
}
Don't you mean oa << *this and ia >> *this? I doubt that you want a new object created in load, but rather this object loaded from the file?
Matthias
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

B Hart wrote:
I've been having some problems storing and loading a class with a map and a multimap. The map contains values that are simple objects of another class. My questions are below. Here is also a link to the same question posted on stackoverflow. Thanks.
http://stackoverflow.com/questions/1676781/boost-serializing-of-object-conta...
See below a main() and two very simple classes. Then per Boost serialization (and what is shown) my questions are:
1) Does class B need the normal overloaded stream insertion operators '<<' and '>>' to be defined? Currently in my real code it doesn't have these.
As stated in: http://www.boost.org/doc/libs/1_40_0/libs/serialization/doc/tutorial.html#si... you provide a template member function: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) or non-intrusively: http://www.boost.org/doc/libs/1_40_0/libs/serialization/doc/tutorial.html#no... namespace boost { namespace serialization { template<class Archive> void serialize(Archive & ar, gps_B& b, const unsigned int version)
2) Does class A in the store() and load() methods need to iterate through the map and multimap containers explicitly, storing/loading their key:value pairs explicitely? e.g. something like:
I assume that I don't need to do this, but am not certain.
As in:
http://www.boost.org/doc/libs/1_40_0/libs/serialization/doc/tutorial.html#st...
#include
3) Assuming class B has only the two data members shown, does it need a default constructor included explicitly? (as opposed to the implicit default constructor)
Not a serialization issues, but what if you ever default construct a B and use it, what state do you want it in?
4) Does B need to have an overide for the comparison operator '>'? I assume that it doesn't since this is a very simple class.
Not sure what this has to do with serialization. Jeff

Finally, any other comments per anything that I've failed to cover is appreciated!
If you want to/can recast your map to a fusion::map, I've made available a serializer for fusion sequences (possibly nested) here : https://svn.boost.org/svn/boost/sandbox/statistics/detail/fusion/boost/stati... derived from fusion's quickstart example. Note, though, that I only ran one example (libs/example) to test it.
participants (5)
-
B Hart
-
er
-
Jeff Flinn
-
Matthias Troyer
-
OvermindDL1