如何使用boost :: multiprecision :: mpq_rational对模板类进行de /序列化

时间:2014-09-29 13:49:54

标签: c++ serialization boost map

我有以下模板类:

#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有一个简单的解决方法吗? 谢谢,

1 个答案:

答案 0 :(得分:0)

Boost Multiprecision序列化的 passthrough 支持:

  

课程numberdebug_adaptorlogged_adaptorrational_adaptor   有&#34;通过&#34;序列化支持需要底层   后端是可序列化的。

     

后端cpp_intcpp_bin_floatcpp_dec_floatfloat128   完全支持Boost.Serialization。

也就是说,后端支持 iff 支持 mailing list

  

> multiprecesion是否会支持boost :: serialization?

     

好问题,还没有。我想应该这样做......但很难   虽然有些后端(例如GMP&#39; s mpf_t)不会往返   来自字符串表示,并且可能具有内部结构   不应该依赖: -

你可以:

  • 使用cpp_rational(由上述文档摘录隐式支持)
  • 使用Boost Rational:How to serialize boost::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;
    }
}