【问题标题】:How to de/serialize a map with template class using boost::multiprecision::mpq_rational如何使用 boost::multiprecision::mpq_rational 使用模板类对地图进行反序列化/序列化
【发布时间】:2014-11-23 22:35:45
【问题描述】:

我有以下模板类:

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

【问题讨论】:

  • 事实上,您应该将问题简化为 /just/ ask how to serialize mpq_rational,因为其余的对于您的问题(或解决方案)并不重要

标签: c++ serialization boost map


【解决方案1】:

passthrough 支持 Boost 多精度序列化:

numberdebug_adaptorlogged_adaptorrational_adaptor 具有需要底层的“通过”序列化支持 后端可序列化。

后端 cpp_intcpp_bin_floatcpp_dec_floatfloat128 有 完全支持 Boost.Serialization。

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

&gt; 多重精度是否/将支持 boost::serialization?

好问题,现在还没有。我想它应该这样做......这很难 尽管某些后端(例如 GMP 的 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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2021-05-08
    • 1970-01-01
    相关资源
    最近更新 更多