我有以下模板类:
#include <map>
#include <boost/array.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/multiprecision/gmp.hpp>
template <class T>
class A {
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & a;
}
public:
T a;
};
我用来创建地图。
map<A<boost::array<int,2> >, int> mmm;
我可以使用boost提供的头文件来使用以下代码序列化/反序列化此代码:
ifstream ifs("filename");
boost::archive::text_iarchive iarch(ifs);
boost::serialization::load<boost::archive::text_iarchive,int,A<boost::array<int,2> > >(iarch,mmm,1);
问题:我想在数组中使用boost::multiprecision::mpq_rational
而不是int
。但是我得到一个很长的错误,主要的抱怨是gmp_backend没有序列化方法:
....
/usr/local/include/boost/serialization/access.hpp:118:9: error: ‘struct boost::multiprecision::backends::gmp_rational’ has no member named ‘serialize’
t.serialize(ar, file_version);
^
使用boost / serialization / map.hpp和mpq_rational有一个简单的解决方法吗? 谢谢,
答案 0 :(得分:0)
Boost Multiprecision序列化的 passthrough 支持:
课程
number
,debug_adaptor
,logged_adaptor
和rational_adaptor
有&#34;通过&#34;序列化支持需要底层 后端是可序列化的。后端
cpp_int
,cpp_bin_float
,cpp_dec_float
和float128
完全支持Boost.Serialization。
也就是说,后端支持 iff 支持 mailing list :
>
multiprecesion是否会支持boost :: serialization?好问题,还没有。我想应该这样做......但很难 虽然有些后端(例如GMP&#39; s mpf_t)不会往返 来自字符串表示,并且可能具有内部结构 不应该依赖: -
你可以:
cpp_rational
(由上述文档摘录隐式支持)使用原始mpz_*
API进行序列化,例如, How to serialize a GMP rational number?
您可以明确地为后端添加序列化支持(请注意,使用gmp API会更有效)
namespace boost { namespace serialization {
template <typename Archive>
void save(Archive& ar, ::boost::multiprecision::backends::gmp_rational const& r, unsigned /*version*/)
{
std::string tmp = r.str(10000, std::ios::fixed);
ar & tmp;
}
template <typename Archive>
void load(Archive& ar, ::boost::multiprecision::backends::gmp_rational& r, unsigned /*version*/)
{
std::string tmp;
ar & tmp;
r = tmp.c_str();
}
} }
BOOST_SERIALIZATION_SPLIT_FREE(::boost::multiprecision::backends::gmp_rational)
这是一个带有简单往返测试的演示 Live On Coliru 。
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/multiprecision/gmp.hpp>
#include <boost/multiprecision/rational_adaptor.hpp>
#include <iostream>
namespace boost { namespace serialization {
template <typename Archive>
void save(Archive& ar, ::boost::multiprecision::backends::gmp_rational const& r, unsigned /*version*/)
{
std::string tmp = r.str(10000, std::ios::fixed);
ar & tmp;
}
template <typename Archive>
void load(Archive& ar, ::boost::multiprecision::backends::gmp_rational& r, unsigned /*version*/)
{
std::string tmp;
ar & tmp;
r = tmp.c_str();
}
} }
BOOST_SERIALIZATION_SPLIT_FREE(::boost::multiprecision::backends::gmp_rational)
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/array.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/serialization.hpp>
#include <map>
template <class T>
class A {
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & a;
}
public:
T a;
bool operator<(A const& o) const { return a<o.a; }
};
#include <sstream>
using KeyElement = boost::multiprecision::mpq_rational;
using Key = A<boost::array<KeyElement,2> >;
using Data = std::map<Key, int>;
int main()
{
std::stringstream ss;
{
Data mmm {
{ Key {{{KeyElement { 1, 2 }, KeyElement { 3, 4 }} }}, 5 },
{ Key {{{KeyElement { 6, 7 }, KeyElement { 8, 9 }} }}, 42 },
};
boost::archive::text_oarchive oa(ss);
oa << mmm;
}
std::cout << "Serialized:\t" << ss.str() << "\n";
{
boost::archive::text_iarchive iarch(ss);
Data mmm;
iarch >> mmm;
std::cout << "Roundtrip:\t";
boost::archive::text_oarchive oa(std::cout);
oa << mmm;
}
}