3

I have my own class containing the following data:

#include <boost/date_time/posix_time/time_serialize.hpp> 
#include <boost/serialization/vector.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
using namespace boost::archive;

class Foo {
// [...]

unsigned int m_length;  
std::vector<boost::posix_time::ptime> m_vecTimestamps;
std::vector<double> m_vecA;
std::vector<double> m_vecB;
std::vector<Point2d> m_vecPos;

Since I included the appropriate headers I am even able to serialize ptime:

// Still class Foo
private:
    friend class boost::serialization::access;

    template <typename Archive>
    void serialize(Archive &ar, const unsigned int version) { 
        ar & m_length; 
        ar & m_vecTimestamps; 
        ar & m_vecA;
        ar & m_vecB;
        ar & m_vecPos; // ooops, error
    }

Well, there is no approach to serialize Point2d since this class is delivered by a further third party library (contains simply 2 double values). So what are my options to write a wrapper which can be used within Foo::serialize? I would like to easily read and write that vector too. An easy example would be nice.

I tried to have a look at time_serialize.hpp but I do not understand how to write a similar approach for Point2d respectively other class types which can not be modified by myself?

Anonymous
  • 4,617
  • 9
  • 48
  • 61

2 Answers2

1

The boost serialization tutorial contains both an intrusive and a non-intrusive example. You need the non-intrusive version which allows you to add a serialize function for Point2d:

namespace boost {
namespace serialization {

template<class Archive>
void serialize(Archive & ar, Point2d & p, const unsigned int version)
{
    ar & p.x;
    ar & p.y;
}
} // namespace serialization
} // namespace boost
m.s.
  • 16,063
  • 7
  • 53
  • 88
  • This works fine for the simple Point2d class. But is there also a solution for the following class: http://codepad.org/1Qp1qSuK – Anonymous Jul 01 '15 at 12:01
  • @Anonymous why would that be different? use `ar & b.value()` – m.s. Jul 01 '15 at 12:04
  • I get two compiler errors. First: "C2679: Binary operator '&': no operator found which accepts 'double'". Second error: "C2088: '&': Invalid for class" (Roughly translated since I am using another language) – Anonymous Jul 01 '15 at 12:15
  • I am accepting your solutions since it answers the original question. Thanks for that! But I would be glad if you could test and extend your answer with the Bar-class. Find an example here: http://codepad.org/r0Hxc33V – Anonymous Jul 01 '15 at 12:25
  • 1
    @Anonymous `operator&` wants its arguments passed via non-const reference, which is not possible for the temporary return value of the function `value()`. You could create a temporary copy of the value and serialize that: http://melpon.org/wandbox/permlink/CD6Iyh1tXse9bTOC – m.s. Jul 01 '15 at 12:30
  • 1
    @m.s. that advice doesn't work. Unless you never want to deserialize. There's a reason why lvalues are required/assumed by the serialization framework. – sehe Jul 01 '15 at 13:44
1

In addition to the other answer

Generically serializing families of types

If you want to non-intrusively implement serialize for points in a generic way, for a "family" of generic types with some common traits, look here e.g.

Serializing with getters

A note about the advice:

[...]You could create a temporary copy of the value and serialize that: – m.s. 54 mins ago

Don't do that! At the very least you need separate load/save handling there. But realistically, just use the last approach shown above, where serialize_impl has full friend access to the class implementation.

If you really can't, you'll have use load/save and possibly load_/save_construct_data in case your type is not default-constructible

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633