Boost :: serialization with mutable members

Using boost :: serialization, what is the "best" way to serialize an object that contains cached derived values โ€‹โ€‹in mutable elements?

class Example { public: Example(float n) : num(n), sqrt_num(-1.0) {} // compute and cache sqrt on first read float get_sqrt() const { if(sqrt_num < 0) sqrt_num = sqrt(num); return sqrt_num; } template <class Archive> void serialize(Archive& ar, unsigned int version) { ... } private: float num; mutable float sqrt_num; }; 

I would like to avoid splitting serialization () into separate save () and load () methods for maintenance.

One suboptimal implementation of serialization:

  template <class Archive> void serialize(Archive& ar, unsigned int version) { ar & num; sqrt_num = -1.0; } 

This handles the case of deserialization, but in the case of serialization, the cached value is killed and needs to be recounted.

What is the best practice in this case?

+4
source share
2 answers

You can check the Archive::is_loading and load cached values โ€‹โ€‹if it is true.

 template <class Archive> void serialize(Archive& ar, unsigned int version) { ar & num; if(Archive::is_loading::value == true) sqrt_num = -1.0; } 
+2
source

Separating save and load methods does not mean that you need to save two copies of the serialization code. You can separate them and then join them again using a common function.

 private: friend class boost::serialization::access; BOOST_SERIALIZATION_SPLIT_MEMBER() template <class Archive> void save(Archive& ar, const unsigned int version) const { const_cast<Example*>(this)->common_serialize(ar, version); } template <class Archive> void load(Archive& ar, const unsigned int version) { common_serialize(ar, version); sqrt_num = -1; } template <class Archive> void common_serialize(Archive& ar, const unsigned int version) { ar & num; } 

You probably noticed const_cast . This is an unfortunate warning against this idea. Although the serialize member function is not constant for save operations, the save member function must be const. Until the object you serialize was originally declared const, it is safe to discard it as shown above. The documentation briefly mentions the need for dropping for const members ; it looks like.

With the above changes, your code will correctly print "2" for ex1 and ex2 , and you will only need to save one copy of the serialization code. The load code contains only code specific for reinitializing the objectโ€™s internal cache; the save function does not apply to the cache.

+3
source

Source: https://habr.com/ru/post/1310063/


All Articles