问题
I'm trying to use the Boost Serialization library to archive Boost ICL interval sets (because I couldn't find any other more or less standard ways to serialize them). I want to split the serialize
function into two functions save
and load
. Sorry to say, I'm stuck in the load
function for now - I can't save even the size of the interval set.
My testing program is below. The compiler complains about the line A << IS.iterative_size()
, which is strange cause the return type of the iterative_size()
function is the size_t
.
#include <fstream>
#include <string>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/icl/discrete_interval.hpp>
#include <boost/icl/interval_set.hpp>
const std::string Filename = "tmp.archive";
typedef boost::icl::discrete_interval<int> Interval;
typedef boost::icl::interval_set<int> IntervalSet;
namespace boost
{
namespace serialization
{
template<class Archive>
void save(Archive& A, const IntervalSet& IS, const unsigned int)
{
A << IS.iterative_size();
// ...
}
template<class Archive>
void load(Archive& A, IntervalSet& IS, const unsigned int)
{
// ...
}
template<class Archive>
inline void serialize(Archive& A, IntervalSet& IS, const unsigned int V)
{
split_free(A, IS, V);
}
}
}
int main()
{
std::ofstream f(Filename);
if (f.good())
{
boost::archive::binary_oarchive oa(f);
IntervalSet s;
s += Interval::closed(100, 200);
oa << s;
f.close();
}
else
{
std::cout << "Error" << std::endl;
}
}
Any thoughts?
(Compiler - GCC 4.8.1, Boost - 1.55.0, OS - Xubuntu 3.11)
回答1:
iterative_size()
doesn't return a lvalue
, which is required. You can't usefully deserialize derived properties anyways (in much the same way as a vector doesn't (de)serialize the size()
member result. Instead, it serializes all data, and the size()
happens to end up being the same in the end.
Also look at
If there is no such default constructor, the function templates
load_construct_data
and perhapssave_construct_data
will have to be overridden. Here is a simple example
From the docs
which can probably be used beneficially in cases where object instances get initialized from (non-default) constructor parameters only.
Update Here's a demo implementation: Live On Coliru
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/icl/discrete_interval.hpp>
#include <boost/icl/interval_set.hpp>
namespace boost { namespace serialization {
template <typename Archive, typename V>
void save(Archive& ar, boost::icl::discrete_interval<V> const& di, unsigned) {
auto const& bb = di.bounds().bits();
auto const& l = di.lower();
auto const& u = di.upper();
ar << bb << l << u;
}
template <typename Archive, typename V>
void load(Archive& ar, boost::icl::discrete_interval<V>& di, unsigned) {
auto bb = di.bounds().bits();
V l, u;
ar >> bb >> l >> u;
di = boost::icl::discrete_interval<V>(l, u, boost::icl::interval_bounds(bb));
}
template <typename Archive, typename V>
void serialize(Archive& ar, boost::icl::discrete_interval<V>& di, unsigned v) {
split_free(ar, di, v);
}
template <typename Archive, typename V>
void save(Archive& ar, boost::icl::interval_set<V> const& is, unsigned) {
auto sz = is.iterative_size();
ar & sz;
for (auto& di : is) ar & di;
}
template <typename Archive, typename V>
void load(Archive& ar, boost::icl::interval_set<V>& is, unsigned) {
is.clear();
size_t sz;
ar & sz;
size_t counter = sz;
while (counter--) {
typename boost::icl::interval_set<V>::value_type di;
ar & di;
is.insert(is.end(), di);
}
assert(is.iterative_size() == sz);
}
template <typename Archive, typename V>
void serialize(Archive& ar, boost::icl::interval_set<V>& is, unsigned v)
{
split_free(ar, is, v);
}
} }
const std::string Filename = "tmp.archive";
typedef boost::icl::discrete_interval<int> Interval;
typedef boost::icl::interval_set<int> IntervalSet;
#include <fstream>
#include <string>
int main()
{
{
std::ofstream f(Filename);
boost::archive::binary_oarchive oa(f);
IntervalSet s;
s += Interval::closed(100, 200);
s += Interval::left_open(30,45);
s += Interval::right_open(77, 78);
oa << s;
}
{
std::ifstream f(Filename);
boost::archive::binary_iarchive ia(f);
IntervalSet s;
ia >> s;
std::cout << "Deserialized: ";
std::copy(s.begin(), s.end(), std::ostream_iterator<Interval>(std::cout, " "));
}
}
Prints:
Deserialized: (30,45] [77,78) [100,200]
来源:https://stackoverflow.com/questions/24004243/combination-of-boost-icl-and-boost-serialization