program with boost::serialization

I am writing program with boost::serialization and output with text archive. after I write the object to a file, I cant read deserialize it correctly. The records being written into the file is different with the records being read out from the file. Is it a bug of boost or there is something wrong with my code. please, someone give me a hint. Thx! My program is as follows.
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <boost/serialization/map.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/version.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include "types.h"

using namespace std;
using namespace boost;
using namespace boost::serialization;
using namespace boost::archive;

int main(int argc,char ** argv)
{
	ofstream out("test.txt");
	if(false == out.is_open()) {
		cout<<"invalid file!"<<endl;
		return EXIT_FAILURE;
	}
	text_oarchive oa(out);
	map<Status,map<Action,double> > Q;
	for(int x1 = 1 ; x1 <= 7 ; x1++)
		for(int y1 = 1 ; y1 <= 6 ; y1++)
			for(int x2 = 1 ; x2 <= 7 ; x2++)
				  for(int y2 = 1 ; y2 <= 6 ; y2++)
					for(int g1 = 0 ; g1 < 3 ; g1++)
						  for(int g2 = 0 ; g2 < 3 ; g2++)
							for(int i = 0 ; i < 5 ; i++)	
								Q[Status(x1,y1,x2,y2,(Status::GraspState)g1,(Status::GraspState)g2)][(Action)i] = 0;
	//the records written into the file
	cout<<Q.size()<<endl;
	oa << Q;
	out.close();
	Q.clear();
	ifstream in("test.txt");
	text_iarchive ia(in);
	ia >> Q;
	//the records read from the file
	cout<<Q.size()<<endl;
}

types.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#ifndef TYPES_H
#define TYPES_H

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/version.hpp>

using namespace boost;
using namespace boost::serialization;

enum Action {LEFT = 0,RIGHT,UP,DOWN,STAND_STILL};
struct Status {
	  friend class boost::serialization::access;
	  template<class Archive> void serialize(Archive & ar,const unsigned int version) {}
  
	  int x1,y1,x2,y2;
	  enum GraspState {FREE = 0,GRASPING_LEFT,GRASPING_RIGHT} g1,g2;
	  Status() {}
	  Status(int xx1,int yy1,int xx2,int yy2,GraspState gg1,GraspState gg2) : x1(xx1),y1(yy1),x2(xx2),y2(yy2),g1(gg1),g2(gg2) {}
	  Status(const Status & q);
	  ~Status() {}
	  friend bool operator<(const Status& idx1,const Status & idx2);
	  friend bool operator==(const Status & idx1,const Status & idx2);
};

Status::Status(const Status & q)
{
          x1 = q.x1; y1 = q.y1; x2 = q.x2; y2 = q.y2; g1 = q.g1; g2 = q.g2;
}

bool operator<(const Status& idx1,const Status & idx2)
{
          if(idx1.x1 < idx2.x1) return true;
          if(idx1.x1 > idx2.x1) return false;
          if(idx1.y1 < idx2.y1) return true;
          if(idx1.y1 > idx2.y1) return false;
          if(idx1.x2 < idx2.x2) return true;
          if(idx1.x2 > idx2.x2) return false;
          if(idx1.y2 < idx2.y2) return true;
          if(idx1.y2 > idx2.y2) return false;
          if(idx1.g1 < idx2.g1) return true;
          if(idx1.g1 > idx2.g1) return false;
          if(idx1.g2 < idx2.g2) return true;
          if(idx1.g2 > idx2.g2) return false;
          return false;
}

bool operator==(const Status & idx1,const Status & idx2)
{
          return idx1.x1 == idx2.x1 && idx1.y1 == idx2.y1 && idx1.x2 == idx2.x2 && idx1.y2 == idx2.y2 && idx1.g1 == idx2.g1 && idx1.g2 == idx2.g2;
}

namespace boost {
	  namespace serialization {
			template<class Archive> inline void save_construct_data(Archive & ar, const Status * i, const unsigned int version) {
				  ar << i->x1 << i->y1 << i->x2 << i->y2 << i->g1 << i->g2;
			}
			template<class Archive> void load_construct_data(Archive & ar,Status * i, const unsigned int version) {
				  int x1,y1,x2,y2;
				  Status::GraspState g1,g2;
				  ar >> x1 >> y1 >> x2 >> y2 >> g1 >> g2;
				  ::new(i) Status(x1,y1,x2,y2,g1,g2);
			}
	  }
}

#endif 

If you haven't already, give this page a read: http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/serialization.html

Salient points:
If your load and save functions are free functions then serialize needs to be a free function also, not a member function. http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/serialization.html#splittingfreefunctions

Note that although the functionality to split the serialize function into save/load has been provided, the usage of the serialize function with the corresponding & operator is preferred.
the implement of serialize function follows the instruction given here http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/serialization.html#constructors . It does not mean to split the save and load functions.
And what pointer is it that you are serializing?

Tried your code and it works fine for me with the following change:
1
2
3
4
template<class Archive> void serialize(Archive & ar,const unsigned int version) 
{
    ar & x1 & y1 & x2 & y2 & g1 & g2;
}
15876
15876
thx, the problem is solved though I dont know why. I implemented the serialize function for non default constructor. I thought that was enough.
Topic archived. No new replies allowed.