[serialization] Serializing a reference

Hello Boost Experts -- And now for my real question. Again, g++ 4.2.1, OS X 10.6.1, boost 1.40. I'm trying to follow the instructions in the document for serializing classes with reference members, which suggests I serialize them as pointers. First, a program which works, that uses pointers and not references: #include <iostream> #include <fstream> #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> struct A { int v; template<class Ar> void serialize(Ar & ar, const unsigned int ver) { ar & v; } }; struct B { A *ap; B(A *ap_) : ap(ap_) {} template<class Ar> void serialize(Ar & ar, const unsigned int ver) {} }; template<class Ar> void save_construct_data(Ar & ar, const B * b, const unsigned int ver) { ar << b->ap; } template<class Ar> void load_construct_data(Ar & ar, B * b, const unsigned int ver) { A * ap_; ar >> ap_; ::new(b)B(ap_); } int main(int ac, char ** argv) { A a; a.v = 10; B * b1p; b1p = new B(&a); const char * fname = "test.bin"; { std::ofstream ofs(fname); boost::archive::binary_oarchive ar(ofs); ar << b1p; } B * b2p; { std::ifstream ifs(fname); boost::archive::binary_iarchive ar(ifs); ar >> b2p; } std::cout << b2p->ap->v << std::endl; return 0; } What I would really like to do is to modify this program so that class B has a reference to class A instead of a pointer. The documentation suggests I do the following: "This raises the question of how and where the objects being referred to are stored and how are they created. Also there is the question about references to polymorphic base classes. Basically, these are the same questions that arise regarding pointers. This is no surprise as references are really a special kind of pointer. We address these questions by serializing references as though they were pointers." The example given after this serializes the address of the referenced object, similar to the above. My translation of that code is: #include <iostream> #include <fstream> #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> struct A { int v; template<class Ar> void serialize(Ar & ar, const unsigned int ver) { ar & v; } }; struct B { A &a; B(A &a_) : a(a_) {} template<class Ar> void serialize(Ar & ar, const unsigned int ver) {} }; template<class Ar> void save_construct_data(Ar & ar, const B * b, const unsigned int ver) { ar << (&(b->a)); } template<class Ar> void load_construct_data(Ar & ar, B * b, const unsigned int ver) { A * ap_; ar >> ap_; ::new(b)B(*ap_); } int main(int ac, char ** argv) { A a; a.v = 10; B * b1p; b1p = new B(a); const char * fname = "test.bin"; { std::ofstream ofs(fname); boost::archive::binary_oarchive ar(ofs); ar << b1p; } B * b2p; { std::ifstream ifs(fname); boost::archive::binary_iarchive ar(ifs); ar >> b2p; } std::cout << b2p->a.v << std::endl; return 0; } This however fails to compile, with the message: Compilation started at Fri Oct 23 15:25:29 make -k debug make all "CXX_FLAGS = -g -fno-inline -m64 -I. -I.. -I/opt/local/include -Wall -Wextra -Wpointer-arith -Wcast-align -Wwrite-strings -Wconversion -Woverloaded-virtual -Wno-sign-compare -Wno-unused -fno-nonansi-builtins" \ "LD_FLAGS = -g -m64" g++ -g -fno-inline -m64 -I. -I.. -I/opt/local/include -Wall -Wextra -Wpointer-arith -Wcast-align -Wwrite-strings -Wconversion -Woverloaded-virtual -Wno-sign-compare -Wno-unused -fno-nonansi-builtins -c test.cc -o test.o test.cc: In function 'void save_construct_data(Ar&, const B*, unsigned int) [with Ar = boost::archive::binary_oarchive]': /opt/local/include/boost/serialization/serialization.hpp:148: instantiated from 'void boost::serialization::save_construct_data_adl(Archive&, const T*, unsigned int) [with Archive = boost::archive::binary_oarchive, T = B]' /opt/local/include/boost/archive/detail/oserializer.hpp:179: instantiated from 'void boost::archive::detail::pointer_oserializer<Archive, T>::save_object_ptr(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::binary_oarchive, T = B]' test.cc:60: instantiated from here test.cc:27: error: no match for 'operator<<' in 'ar << (A*)b->B::a' /opt/local/include/boost/archive/detail/interface_oarchive.hpp:63: note: candidates are: Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = A*, Archive = boost::archive::binary_oarchive] make[1]: *** [test.o] Error 1 make[1]: Target `all' not remade because of errors. make: *** [debug] Error 2 Compilation exited abnormally with code 2 at Fri Oct 23 15:25:30 What am I doing wrong? Best regards, Ben

AMDG Ben wrote:
template<class Ar> void save_construct_data(Ar & ar, const B * b, const unsigned int ver) { ar << (&(b->a)); }
<snip> test.cc:27: error: no match for 'operator<<' in 'ar << (A*)b->B::a' /opt/local/include/boost/archive/detail/interface_oarchive.hpp:63: note: candidates are: Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&)
Compilation exited abnormally with code 2 at Fri Oct 23 15:25:30
What am I doing wrong?
You're trying to serialize an rvalue. In Christ, Steven Watanabe

From: Steven Watanabe <watanabesj@gmail.com>
Ben wrote:
template<class Ar> void save_construct_data(Ar & ar, const B * b, const unsigned int ver) { ar << (&(b->a)); }
<snip>
You're trying to serialize an rvalue.
thanks for pointing out my error. how do i get around it? i am not a C++ expert but how do i serialize the reference as a pointer? i tried various castings to no avail. by the way, what i wrote was copied nearly verbatim from the documentation template<class Archive> inline void save_construct_data( Archive & ar, const my_class * t, const unsigned int file_version ){ // save data required to construct instance ar << t.member1; // serialize reference to object as a pointer ar << & t.member2; } which seems like it wouldn't compile, since t is a pointer so t.member2 doesn't seem right. thanks, and best regards, ben
participants (2)
-
Ben
-
Steven Watanabe